C# - Array transposing bit level - c#

I have an array of 10 x 8 bit(bytes), named Matrix[10], e.g.
byte[] Matrix = new byte[] {
0b01111011,
0b10001100,
0b10101101,
0b10100001,
0b11010110,
0b00011100,
0b00111000,
0b11001111,
0b01111011,
0b10101010,
};
What I want to do is create another array named Matrix_res10 which will have 8 x 10bit (used Int32) elements:
int[] Matrix_res10 = new int[] {
0b0111100101,
0b1000100110,
0b1011001011,
0b1000111010,
0b1110011111,
0b0110110100,
0b1000100111,
0b1011000110
};
Additional explanation in the attached "description" picture.
description
Now, I was able to do it, but I feel the code is too complicated, and can be made simpler, or more logical :)
Any tips ?
my code:
private void button11_Click(object sender, EventArgs e)
{
Int32 i,j;
byte temp;
Random r = new Random();
richTextBox5.Clear();
richTextBox6.Clear();
for (i = 0; i < 10; i++)
{
Matrix[i] = Convert.ToByte(r.Next(0,255));// initialize the matrix with random bytes 0-255
richTextBox5.Text += Convert.ToString(Matrix[i], 2).PadLeft(8, '0')+"\n";//print it
}
for (i = 0; i < 8; i++)
{
Matrix_res10[i] = 0;
for (j = 0; j < 10; j++)
{
temp = (byte)(Matrix[j] << i);
temp = (byte)(temp >> 7);
Matrix_res10[i] += temp*(long)(Math.Pow(2, 9-j)); //convert the bits to a int
}
}
for (i = 0; i < 8; i++)
{
richTextBox6.Text += Convert.ToString(Matrix_res10[i],2).PadLeft(10,'0') + "\n";
}
}

All you have to do is to compute what is jth bit of ith item:
byte[] Matrix = new byte[] {
0b01111011,
0b10001100,
0b10101101,
0b10100001,
0b11010110,
0b00011100,
0b00111000,
0b11001111,
0b01111011,
0b10101010,
};
// 8 - byte has 8 bits; more exact: new int[sizeof(byte) * 8];
// int[] - we have to store 10 bits, that's why byte is not long enough
int[] Matrix_res10 = new int[8];
for (int i = 0; i < Matrix_res10.Length; ++i)
for (int j = 0; j < Matrix.Length; ++j)
Matrix_res10[i] |= ((Matrix[j] >> (Matrix_res10.Length - i - 1)) & 1) <<
(Matrix.Length - j - 1);
Let's have a look at the result:
string report = string.Join(Environment.NewLine, Matrix_res10
.Select(item => Convert.ToString(item, 2).PadLeft(Matrix.Length, '0')));
Console.Write(report);
Outcome:
0111100101
1000100110
1011001011
1000111010
1110011111
0110110100
1000100111
1011000110

A bit of binary arithmetic might help here:
static int[] Transpose(byte[] x) {
var result = new int[8];
for (int i = 7; i >= 0; i--) {
for (int j = 0; j < x.Length; j++) {
// get i-th bit of byte
var mask = 1 << i;
var bit = (x[j] & mask) >> i;
// set that bit at j-th position of target number
result[7 - i] |= bit << (x.Length - 1 - j);
}
}
return result;
}

Related

Why is My Base 10 LSD Radix-Sort Faster Than My Bit-Shifted Radix Sort?

So I was experimenting with different kinds of Radix sort for a school project where we have to sort 500,000 random integers (that I generate myself, with a bounds between 0 to MaxValue for each integer) as quickly as possible. I first made a base 10 LSD (Least Significant Digit) Radix sort that averages around 110 to 115ms for sorting 500,000 random integers. Here's the code for it:
public static int[] RadixSort(int[] RandomNumbers)
{
List<int>[] Buckets = new List<int>[10];
int singleDigit = 0;
int[] temp;
int[] mult = new int[10] {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
for (int z = 0; z < 10; z++)
{
Buckets[0] = new List<int>();
Buckets[1] = new List<int>();
Buckets[2] = new List<int>();
Buckets[3] = new List<int>();
Buckets[4] = new List<int>();
Buckets[5] = new List<int>();
Buckets[6] = new List<int>();
Buckets[7] = new List<int>();
Buckets[8] = new List<int>();
Buckets[9] = new List<int>();
if (z == 0)
{
temp = (int[])RandomNumbers.Clone();
}
else
{
temp = (int[])RandomNumbers.Clone();
for (int i = 0; i < SIZE; i++)
{
temp[i] /= (mult[z]);
}
}
for (int i = 0; i < SIZE; i++)
{
singleDigit = temp[i] % 10;
Buckets[singleDigit].Add(RandomNumbers[i]);
}
List<int> NewList = new List<int>(SIZE);
for (int i = 0; i < 10; i++)
{
NewList.AddRange(Buckets[i]);
}
int[] NewArray = NewList.ToArray();
RandomNumbers = NewArray;
}
return RandomNumbers;
}
However, I heard that using binary in a bit-shift Radix sort was faster. So I created a mask-based bit-shift Radix sort that overall looks less cluttered and has less operations going on within it, but its average sort speed is around 250ms. Here's the code for it:
public static int[] BitShiftRadixSort(int[] RandomNumbers)
{
List<int>[] Buckets = new List<int>[2];
int binary;
int mask;
for (int shift = 0; shift < 32; shift++)
{
Buckets[0] = new List<int>(SIZE);
Buckets[1] = new List<int>(SIZE);
mask = 1 << shift;
for (int i = 0; i < SIZE; i++)
{
binary = RandomNumbers[i] & mask;
if (binary != 0)
{
Buckets[1].Add(RandomNumbers[i]);
}
else
{
Buckets[0].Add(RandomNumbers[i]);
}
}
List<int> NewList = new List<int>(SIZE);
for (int i = 0; i < 2; i++)
{
NewList.AddRange(Buckets[i]);
}
int[] NewArray = NewList.ToArray();
RandomNumbers = NewArray;
}
return RandomNumbers;
}
I was expecting the bit-shift to be faster than the LSD Radix sort but that doesn't appear to be the case. Are mathematical operations in C# heavily optimized? I'll appreciate everyone's input!
Using Matt Timmermans suggestion of using base 256, this version for unsigned integers takes about 10ms for 500,000 32 bit unsigned integers. For signed integers, you would need to complement the sign bit and treat them as unsigned integers (then complement the sign back back).
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace RadixSort
{
class Program
{
static void RadixSort(uint [] a, uint count)
{
uint [,] mIndex = new uint [4,256]; // count / index matrix
uint [] b = new uint [count]; // allocate temp array
uint i,j,m,n;
uint u;
for(i = 0; i < count; i++){ // generate histograms
u = a[i];
for(j = 0; j < 4; j++){
mIndex[j,(u & 0xff)]++;
u >>= 8;
}
}
for(j = 0; j < 4; j++){ // convert to indices
m = 0;
for(i = 0; i < 256; i++){
n = mIndex[j,i];
mIndex[j,i] = m;
m += n;
}
}
for(j = 0; j < 4; j++){ // radix sort
for(i = 0; i < count; i++){ // sort by current lsb
u = a[i];
m = (u>>((int)(j<<3)))&0xff;
b[mIndex[j,m]++] = u;
}
uint [] t = a; // swap references
a = b;
b = t;
}
}
static void Main(string[] args)
{
const int SIZE = 500000;
uint [] a = new uint[SIZE];
uint u;
Random r = new Random(1);
Stopwatch sw = new Stopwatch();
for (uint i = 0; i < a.Length; i++)
{
u = (uint)r.Next(1 << 16);
u = (u << 16) | (uint)r.Next(1 << 16);
a[i] = u;
}
sw.Start();
RadixSort(a, (uint)a.Length);
sw.Stop();
for (uint i = 1; i < a.Length; i++)
{
if(a[i] < a[i-1])
{
Console.WriteLine("failed");
break;
}
}
Console.WriteLine("milliseconds: {0:D}\n",sw.ElapsedMilliseconds);
}
}
}

Trying all possibilities for a number grid

I'm trying to solve a maths problem programmatically. I have a 6x5 grid, with a few predefined numbers, and I have to find the rest of the numbers with the condition of all rows and columns should total 34.
//Grid
static int[][] sq;
static void Main(string[] args)
{
sq = new int[6][];
for (int i = 0; i < sq.Length; i++)
{
sq[i] = new int[5] { -250, -250, -250, -250, -250, };
}
SetDefaults();
Print();
Console.WriteLine("Press enter to quit...");
Console.ReadLine();
}
static void SetDefaults()
{
sq[0][0] = 7;
sq[0][1] = 6;
sq[0][2] = 8;
sq[2][2] = 9;
sq[2][3] = 8;
sq[2][4] = 5;
sq[3][1] = 9;
sq[3][3] = 7;
sq[3][4] = 5;
sq[4][0] = 4;
sq[4][1] = 4;
sq[4][4] = 9;
sq[5][0] = 8;
sq[5][2] = 3;
sq[5][3] = 6;
sq[5][4] = 8;
}
static void Print()
{
Console.WriteLine();
for (int i = 0; i<sq.Length; i++)
{
for (int ii = 0; ii < sq[i].Length; ii++)
{
Console.Write("[" + sq[i][ii] + "\t]");
}
Console.WriteLine();
}
Console.WriteLine();
}
I think one method is try all the possibilities, with a range of 500 numbers, from -250 to 250, or an incremental range (-1,1, then -2,2, etc), but I don't know how to do this programmatically and much less efficiently.
I have a 6x5 grid
The number of columns and rows is different?
Then, no matter what's in the grid, there is no solution at all to make all sums equal. Consequently there is nothing to code.
Not putting too much effort in it, but if you are really thinking of enumerating something, you could (but shouldn't) try this naive and unoptimized approach (for a range of integers between 0 and 15):
for (int a = 0; a < 16; a++) {
for (int b = 0; b < 16; b++) {
for (int c = 0; c < 16; c++) {
for (int d = 0; d < 16; d++) {
for (int e = 0; e < 16; e++) {
for (int f = 0; f < 16; f++) {
for (int g = 0; g < 16; g++) {
for (int h = 0; h < 16; h++) {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
for (int m = 0; m < 16; m++) {
for (int n = 0; n < 16; n++) {
// test all columns and rows:
// test if 7 + 8 + 9 + a + b == 34
// test if c + d + e + f + g == 34
...
}}}}}}}}}}}}}}
Certainly possible to optimize a lot, like:
for (int a = 0; a < 16; a++) {
var b = 34 - 7 - 8 - 9 - a;
for (int c = 0; c < 16; c++) {
for (int d = 0; d < 16; d++) {
for (int e = 0; e < 16; e++) {
for (int f = 0; f < 16; f++) {
var g = 34 - c - d - e - f;
for (int h = 0; h < 16; h++) {
var i = 34 - 9 - 8 - 5 - h;
for (int j = 0; j < 16; j++) {
var k = 34 - 9 - 7 - 5 - j;
for (int l = 0; l < 16; l++) {
var m = 34 - 4 - 4 - 9 - l;
var n = 34 - 8 - 3 - 6 - 8;
// test all columns only:
// test if 7 + c + h + 4 + 8 == 34
...
}}}}}}}}
But in the end, best optimization is to return "no solution" directly.

Shifting a BitArray

I'm currently trying to shift a BitArray while keeping its length. Since there's no built-in method I'm struggling to build one but can't make it work, unfortunatly.
My initial BitArray code sets a length of 421 for the BitArray.
var b = new BitArray(length: 421);
Than, I'm assigning some values for testing. For instance:
b.Set(0, true);
b.Set(1, true);
However, I can't figure out how to shift the bit array.
Attempts:
- I thought that I could convert it into long and than make the bit manipulation. However, long does not match my exact BitArray length, which results in errors later on when I apply bitwise operations on two BitArrays (my full requirements is (array1 |= array2 >> 20).
- I tried to convert the BitArray into byte[], do the manipulation and return it (see Bit shifting N bits):
public static byte[] ToBytesArray(this BitArray array, int startIndex, int count)
{
// Get the size of bytes needed to store all bytes
int bytesize = count / ByteLength;
// Any bit left over another byte is necessary
if (count % ByteLength > 0)
{
bytesize++;
}
// For the result
byte[] bytes = new byte[bytesize];
// Must init to good value, all zero bit byte has value zero
// Lowest significant bit has a place value of 1, each position to
// to the left doubles the value
byte value = 0;
byte significance = 1;
int bytepos = 0;
int bitpos = startIndex;
while (bitpos - startIndex < count)
{
// If the bit is set add its value to the byte
if (array[bitpos])
value += significance;
bitpos++;
if (bitpos % ByteLength == 0)
{
// A full byte has been processed, store it
// increase output buffer index and reset work values
bytes[bytepos] = value;
bytepos++;
value = 0;
significance = 1;
}
else
{
// Another bit processed, next has doubled value
significance *= 2;
}
}
return bytes;
}
public static BitArray ShiftLeft(this BitArray array, int bitcount)
{
byte[] value = array.ToBytesArray();
byte[] temp = new byte[value.Length];
if (bitcount >= 8)
{
Array.Copy(value, bitcount / 8, temp, 0, temp.Length - (bitcount / 8));
}
else
{
Array.Copy(value, temp, temp.Length);
}
if (bitcount % 8 != 0)
{
for (int i = 0; i < temp.Length; i++)
{
temp[i] <<= bitcount % 8;
if (i < temp.Length - 1)
{
temp[i] |= (byte)(temp[i + 1] >> 8 - bitcount % 8);
}
}
}
return new BitArray(temp);
}
However, byte's length is 8, which can't fit well with my length too. The result is 416 or 424 (another byte) instead of 421.
Finally, I tried the "primitive" way:
for (int i = 0; i < bitcount; i++)
{
var lastValue = array[0];
for (var j = 0; j < array.Length - 1; j++)
{
array[j] = array[j + 1];
}
array[array.Length - 1] = lastValue;
}
I also check up SO (e.g. BitArray - Shift bits) but nothing worked for me.
Any help will be very appreciated!
Still not 100% sure what's the issue. Here's a naive implementation:
void Main()
{
// Creates and initializes a BitArrays of size 7 (you have 421).
bool[] myBools = new bool[7] { true,false,false,true,true,false,true };
BitArray myBA1 = new BitArray(myBools );
PrintBitArray(myBA1); // 1001101
PrintBitArray(ShiftRight(myBA1)); // 0100110
PrintBitArray(ShiftLeft (myBA1)); // 0011010
}
BitArray ShiftRight(BitArray aSource) {
bool[] new_arr = new bool[( aSource.Count)];
for (int i = 0; i < aSource.Count -1; i++)
new_arr[i+1] = aSource[i];
return new BitArray(new_arr);
}
BitArray ShiftLeft(BitArray aSource) {
bool[] new_arr = new bool[( aSource.Count)];
for (int i = 0; i < aSource.Count -1; i++)
new_arr[i] = aSource[i+1];
return new BitArray(new_arr);
}
string PrintBitArray(BitArray aSource) {
StringBuilder sb = new StringBuilder();
foreach (var bit in aSource)
{
sb.Append( (bool)bit ? 1 : 0 );
}
return sb.ToString();
}
Note how bits are copied in the loops, and that the third PrintBitArray is done on the original input, not on the outcome of the second.
public static bool[] Left_shiftBitArray(bool[] Array, int count)
{
Array = BitArray_LRotat(Array, count);
for (int i=Array.GetLength(0)-1; i>=(Array.GetLength(0)-count); i--)
{
Array[i] = false;
}
return Array;
}
public static bool[] BitArray_LRotat(bool[] input, int x)
{
//bool [] temp= new bool[input.Length];
bool[] final = new bool[input.Length];
for (int i = input.Length; i > x; i--)
{
final[i - x - 1] = input[i - 1];
}
for (int i = x; i > 0; i--)
{
final[(input.Length) - i] = input[x - i];
}
return final;
}

Need to optimise counting positive and negative values

I need to optimise code that counts pos/neg values and remove non-qualified values by time.
I have queue of values with time-stamp attached.
I need to discard values which are 1ms old and count negative and positive values. here is pseudo code
list<val> l;
v = q.dequeue();
deleteold(l, v.time);
l.add(v);
negcount = l.count(i => i.value < 0);
poscount = l.count(i => i.value >= 0);
if(negcount == 10) return -1;
if(poscount == 10) return 1;
I need this code in c# working with max speed. No need to stick to the List. In fact arrays separated for neg and pos values are welcome.
edit: probably unsafe arrays will be the best. any hints?
EDIT: thanks for the heads up.. i quickly tested array version vs list (which i already have) and the list is faster: 35 vs 16 ms for 1 mil iterations...
Here is the code for fairness sake:
class Program
{
static int LEN = 10;
static int LEN1 = 9;
static void Main(string[] args)
{
Var[] data = GenerateData();
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 30; i++)
{
sw.Reset();
ArraysMethod(data, sw);
Console.Write("Array: {0:0.0000}ms ", sw.ElapsedTicks / 10000.0);
sw.Reset();
ListMethod(data, sw);
Console.WriteLine("List: {0:0.0000}ms", sw.ElapsedTicks / 10000.0);
}
Console.ReadLine();
}
private static void ArraysMethod(Var[] data, Stopwatch sw)
{
int signal = 0;
int ni = 0, pi = 0;
Var[] n = new Var[LEN];
Var[] p = new Var[LEN];
for (int i = 0; i < LEN; i++)
{
n[i] = new Var();
p[i] = new Var();
}
sw.Start();
for (int i = 0; i < DATALEN; i++)
{
Var v = data[i];
if (v.val < 0)
{
int x = 0;
ni = 0;
// time is not sequential
for (int j = 0; j < LEN; j++)
{
long diff = v.time - n[j].time;
if (diff < 0)
diff = 0;
// too old
if (diff > 10000)
x = j;
else
ni++;
}
n[x] = v;
if (ni >= LEN1)
signal = -1;
}
else
{
int x = 0;
pi = 0;
// time is not sequential
for (int j = 0; j < LEN; j++)
{
long diff = v.time - p[j].time;
if (diff < 0)
diff = 0;
// too old
if (diff > 10000)
x = j;
else
pi++;
}
p[x] = v;
if (pi >= LEN1)
signal = 1;
}
}
sw.Stop();
}
private static void ListMethod(Var[] data, Stopwatch sw)
{
int signal = 0;
List<Var> d = new List<Var>();
sw.Start();
for (int i = 0; i < DATALEN; i++)
{
Var v = data[i];
d.Add(new Var() { time = v.time, val = v.val < 0 ? -1 : 1 });
// delete expired
for (int j = 0; j < d.Count; j++)
{
if (v.time - d[j].time < 10000)
d.RemoveAt(j--);
else
break;
}
int cnt = 0;
int k = d.Count;
for (int j = 0; j < k; j++)
{
cnt += d[j].val;
}
if ((cnt >= 0 ? cnt : -cnt) >= LEN)
signal = 9;
}
sw.Stop();
}
static int DATALEN = 1000000;
private static Var[] GenerateData()
{
Random r = new Random(DateTime.Now.Millisecond);
Var[] data = new Var[DATALEN];
Var prev = new Var() { val = 0, time = DateTime.Now.TimeOfDay.Ticks};
for (int i = 0; i < DATALEN; i++)
{
int x = r.Next(20);
data[i] = new Var() { val = x - 10, time = prev.time + x * 1000 };
}
return data;
}
class Var
{
public int val;
public long time;
}
}
To get negcount and poscount, you are traversing the entire list twice.
Instead, traverse it once (to compute negcount), and then poscount = l.Count - negcount.
Some ideas:
Only count until max(negcount,poscount) becomes 10, then quit (no need to count the rest). Only works if 10 is the maximum count.
Count negative and positive items in 1 go.
Calculate only negcount and infer poscount from count-negcount which is easier to do than counting them both.
Whether any of them are faster than what you have now, and which is fastest, depends among other things on what the data typically looks like. Is it long? Short?
Some more about 3:
You can use trickery to avoid branches here. You don't have to test whether the item is negative, you can add its negativity to a counter. Supposing the item is x and it is an int, x >> 31 is 0 for positive x and -1 for negative x. So counter -= x >> 31 will give negcount.
Edit: unsafe arrays can be faster, but shouldn't be in this case, because the loop would be of the form
for (int i = 0; i < array.Length; i++)
do something with array[i];
Which is optimized by the JIT compiler.

C# FFT Implementation not producing expected results

I'm trying to implement, in C#, for my own learning, an FFT algorithm described here:
https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm
under "Data reordering, bit reversal, and in-place algorithms".
My code is as follows, with some background operator overloading for the "cplx" structure to allow me to do arithmetic on these objects.
Bitreverse seems to work fine, and so does the "twiddle factor" calculation, so I'm not sure where I've gone wrong. The code looks awfully similar to the pseudocode given on the wiki page.
public cplx[] FFT(cplx[] x)
{
//Bitreverse Copy
cplx[] a = BitReverse(x);
//Number of points
int n = a.Length;
for (int s = 1; s <= Math.Log(n); s++)
{
int m = (int)Math.Pow(2,s);
cplx w_m = Omega(m);
for (int k = 0; k < n; k += m)
{
cplx w = new cplx(1, 0);
for(int j = 0; j < m/2; j++)
{
cplx t = w * a[k + j + (m / 2)];
cplx u = a[k + j];
a[k + j] = u + t;
a[k + j + (m / 2)] = u - t;
w = w * w_m;
}
}
}
return a;
}
I'm testing it with an input array of an origin-impulse with 8 samples, which should produce a constant output.
Instead, I'm getting 4 ones and 4 zeros, in that order.
As an aside, I assume that in the pseudocode:
for k = 0 to n-1 by m
Refers to for(k = 0; k < n; k += m) although I'm not sure that's right.
Hopefully someone can shed some light on my incompetence!
Cheers.
Here's the code for bitreversal and the omega calculation.
private int Rev(int x, int k)
{
int reversed = 0;
for (int i = 0; i < k; i++)
{
reversed |= (x & (1 << i)) != 0 ? 1 << (k - 1 - i) : 0;
}
return reversed;
}
public cplx[] BitReverse(cplx[] x)
{
cplx[] r = new cplx[x.Length];
int bits = (int)Math.Log(x.Length, 2);
for(int k = 0; k < x.Length; k++)
{
r[Rev(k, bits)] = x[k];
}
return r;
}
private cplx Omega(int m)
{
float x = (- 2 * (float)Math.PI) / m;
return new cplx((float)Math.Cos(x), (float)(Math.Sin(x)));
}
I should have been using log2(n) when I was using Math.Log().

Categories