rewrite array manipulations from C++ to C# - c#

I have a C++ code that I'm trying to reuse on my C# project and I need some help.
Here is the subject
for (int i = 0; i < numOfSamples; i++)
{
*(((double*)m_Buffer) + i)
= max(*(((double*)m_Buffer) + i*4), *(((double*)m_Buffer) + i*4 + 1));
}
where m_Buffer is array of float. This part of code read each 2 "floats" of array as a one "double" and then do some manipulations (shift it, choose max etc.)
The question is - how can I do the same operation in C#.
For example, I have an array [12,45,26,32,07,89,14,11] and I have to transform items in position 0 and 1 (12 and 45) so that I will get a new number (type of double) where highest (I'm not sure - maybe lowest) part of bits will be formed from 12 and lowest - from 45

It should be something like:
for (int i = 0; i < numOfSamples; i++)
{
m_Buffer[i] = Math.Max(m_Buffer[i * 4], m_Buffer[i * 4 + 1]);
}
Where m_Buffer must be an array of at least numOfSamples * 4 + 1 elements.

So, I got the solution. Key point here is a structure
[StructLayout(LayoutKind.Explicit)]
struct MyStruct
{
[FieldOffset(0)]
public double Double;
[FieldOffset(0)]
public float Float1;
[FieldOffset(4)]
public float Float2;
}
I simply create a new array and put array[2*i] to Float1 and array[2*i+1] to Float2. Then apply Math.Max to each new_array[i].Double

Related

How to encode a decimal number to binary in 16 bits in C#?

The problem is asking :
The user gives me integer n,
I convert it to binary in 16 bits,
inverse the binary,
then decode the inverse binary into a new integer.
example:
14769 is 0011100110110001 (the 2 zeros in the front are the problem for me)
inverse the binary:
1000110110011100
Decode:
36252
I wrote the code but when I convert to binary it only gives me
11100110110001 without 00 in front, so the whole inverse binary will change and the new integer will be different.
This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace HelloWorld
{
public class Program
{
public static void Main(string[] args)
{
long n, n1, p, i, r, sum, inv, inv1, newint;
Console.WriteLine("give n:");
n=long.Parse(Console.ReadLine());
n1=n;
p=1;
sum=0;
i=n;
//for below is for the binary representation of n
for(i=n;i!=0;i=i/2)
{
r=i%2;
sum=sum+r*p;
p=p*10;
}
inv=0;
//for below is to inverse the above binary representation
for(i=sum;i!=0;i=i/10)
{
r=i%10;
inv=10*inv+r;
}
inv1=inv;
newint=0;
p=0;
//for below is to decode the inverse binary to its decimal representation
for(i=inv;i!=0;i=i/10)
{
r=i%10;
newint=newint+r*(long)Math.Pow(2,p);
p=p+1;
}
Console.WriteLine("The number that you gave = {0} \nIts binary
representation = {1} \n\nThe inverse binary representation = {2} \nThe integer corresponding to the inverse binary number = {3}", n1, sum, inv1, newint);
}
}
}
So how can i encode on 16 bits?
Edit:
1)We didn't learn built in functions
2)We didn't learn padding or
Convert.Int...
3)We only know the for loop (+ while loop but better not use it)
4)We can't use strings either
You could reverse the bits using some simple bitwise operators.
ushort num = 14769;
ushort result = 0;
// ushort is 16 bits, therefore exactly 16 iterations is required
for (var i = 0; i < 16; i++, num >>= 1){
// shift result bits left by 1 position
result <<= 1;
// add the i'th bit in the first position
result |= (ushort)(num & 1);
}
Console.WriteLine(result); //36252
You can try using Convert to obtain binary representation and Aggregate (Linq) to get back decimal:
using System.Linq;
...
int value = 14769;
int result = Convert
.ToString(value, 2) // Binary representation
.PadLeft(16, '0') // Ensure it is 16 characters long
.Reverse() // Reverse
.Aggregate(0, (s, a) => s * 2 + a - '0'); // Back to decimal
Console.Write($"{value} => {result}");
Output:
14769 => 36252
Edit: Loop solution (if you are not allowed to use the classes above...)
int value = 14769;
int result = 0;
for (int i = 0, v = value; i < 16; ++i, v /= 2)
result = result * 2 + v % 2;
Console.Write($"{value} => {result}");
Explanation (how for above works):
First of all how can we get all 16 bits of the number? We can use standard algorithm based on remainder:
14769 / 1 % 2 == 1,
14769 / 2 % 2 == 0,
14769 / 4 % 2 == 0,
14769 / 8 % 2 == 0,
14769 / 16 % 2 == 1,
...
these are the bits from right to left: 11100110110001. Typical code can be
int v = value; // we don't want to change value, let's work with its copy - v
for (int i = 0; i < 16; ++i) {
// rightmost bit
int bit = v % 2;
// we divide v by to to get rid of the rightmost bit
v = v / 2;
}
Note that we compute bits from right to left - in reverse order - the very order we are looking for! How can we build result from these bits?
result = bit0 + 2 * (bit1 + 2 * (bit2 + ...))))..)
So we can easily modify our loop into
int result = 0;
int v = value; // we don't want to change value, let's work with its copy - v
for (int i = 0; i < 16; ++i) {
// rightmost bit
int bit = v % 2;
result = result * 2 + bit;
// we divide v by to to get rid of the rightmost bit
v = v / 2;
}
Finally, if we get rid of bit and make v declared within loop we can get my loop solution

BinaryReader returning very large doubles. What type of value should I be returning?

I'm trying to read a binaryfile. I don't know the structure, but I do have some code written in R that can read it. I'm not familiar with R but have made some progress converting it to C# and struggle at the last bit.
I'm at a point where I need to list out results which I would expect to be a series of float or double.
The R code looks like this (I've removed some of the logic to keep it short):
Rcpp::NumericVector GetSwmmResult(int iType, int iIndex, int vIndex)
{
int offset;
std::vector<float> resultvec(SWMM_Nperiods);
size_t size;
// --- compute offset into output file
for ( int i=1; i<=SWMM_Nperiods; ++i)
{
offset = StartPos + (i-1)*BytesPerPeriod + 2*RECORDSIZE;
if ( iType == SUBCATCH )
{
offset += RECORDSIZE*(iIndex*SubcatchVars + vIndex);
}
else return wrap(resultvec);
// --- re-position the file and read the result
fseek(Fout, offset, SEEK_SET);
size = fread(&resultvec[i-1], RECORDSIZE, 1, Fout);
}
return wrap(resultvec);
}
In C# I expected to do something as follows, where br is my BinaryReader object:
public List<double> GetSwmmResult(int iType, int iIndex, int vIndex)
{
int offset;
List<double> resultvec = new();
int size;
// --- compute offset into output file
Debug.WriteLine("SWMM_Nperiods count = " + SWMM_Nperiods);
for (int i = 1; i <= SWMM_Nperiods; i++)
{
Debug.WriteLine("SWMM_Nperiods " + i);
offset = StartPos + (i - 1) * BytesPerPeriod + 2 * RECORDSIZE;
if (iType == SUBCATCH)
{
offset += RECORDSIZE * (iIndex * SubcatchVars + vIndex);
}
else
{
return resultvec;
}
// --- re-position the file and read the result
br.BaseStream.Position = offset;
resultvec.Add(br.ReadDouble());
Debug.WriteLine(resultvec[i - 1]);
}
return resultvec;
}
But my C# just returns a load of very large numbers like:
5.058993159887922E-15
3.10628841909217E-16
5.477524451492502E-17
I'm expecting a series of numbers, but in the 100's or 1000's, not such large numbers.
Can anybody see how I should be returning values in my C# code using the R function above as a guide? There's a variable in the R code called SEEK_SET. It's not declared anywhere, so I don't understand how it's being used, but suspect it may be what I'm missing.

Finding Matching Strings Algorithm

I have very long 5 strings (the number of strings may change).There is no fixed format for these strings. I will provide a number which will indicate the length of the substring. I want to find the matching substrings with the given length. For example the strings are:
1. abcabcabc
2. abcasdfklop
string length: 3
Given these values the output will be something like this:
Match #1:
Matched string : "abc"
Matches in first string: 3
Matching positions: 0,3,6
Matches in second string: 1
Match positions: 0
Match #2:
Matched string : "bca"
Matches in first string: 2
Matching positions: 1,4
Matches in second string: 1
Match positions: 1
I managed to do it in 4 foreach statement. But it seemed to me too unefficient. Especially if the input sizes are very big.Is there any suggestion or short way to manage this more efficient in c#?
You can do this with a suffix array. (Suffix trees will work fine too, but they require a bit more space, time, and care in implementation.)
Concatenate your two strings, separating them with a character that occurs in neither one. Then build a suffix array. Then you can read off your answer.
Standard suffix arrays give you a lexicographically sorted array of pointers to suffixes of the string together with a "longest common prefix length" array telling you how long the longest common prefix of two lexicographically consecutive suffixes is.
It is fairly straightforward to use the longest common prefix length array to get the information you want; find all maximal subarrays of the longest common prefix length array for which the longest common prefix length is at least the query length, then, for each one that has a match both in the first string and in the second string, report the appropriate prefix and report that it occurs K+1 times, where K is the length of the maximal subarray.
Another approach that's easier to code is to hash all substrings of the appropriate length. You can do this easily with any rolling hash function. Store a dynamic array of pointers into the strings for each hash; once you've hashed all the strings, iterate over all of the hashes that came up and look for matches. You'll need to deal with the false positives somehow; one (probabilistic) approach is to use several hash functions until the false positive probability is acceptably small. Another approach, which is likely only acceptable in the case where you have few matches, is to compare the strings directly.
If you managed to do this in 4 foreach statements that are not nested then you should be good and you probably don’t need to optimize.
Here is something I’d try.
Create a structure that looks something like this
class SubString
{
string str;
int position;
}
Divide both strings into all possible substrings and store these into one array. This has a O(n2) complexity.
Now sort these arrays by string length ( O(n*log(n)) complexity) and go through both of these to identify matches.
You’ll need additional structure to hold the results and this probably needs some more tweaking but you see where this is going.
You could use a variant of suffix tree to solve this problem. http://en.wikipedia.org/wiki/Longest_common_substring_problem
Also check this out: Algorithm: Find all common substrings between two strings where order is preserved
If using very large strings, memory may become a problem. The code below finds the longest common substring and writes over the variable containing smaller common substrings, but could easily be altered to push the index and length to a list which is then returned as an array of strings.
This is refactored C++ code from Ashutosh Singh at https://iq.opengenus.org/longest-common-substring-using-rolling-hash/ - this will find the substring in O(N * log(N)^2) time and O(N) space
using System;
using System.Collections.Generic;
public class RollingHash
{
private class RollingHashPowers
{
// _mod = prime modulus of polynomial hashing
// any prime number over a billion should suffice
internal const int _mod = (int)1e9 + 123;
// _hashBase = base (point of hashing)
// this should be a prime number larger than the number of characters used
// in my use case I am only interested in ASCII (256) characters
// for strings in languages using non-latin characters, this should be much larger
internal const long _hashBase = 257;
// _pow1 = powers of base modulo mod
internal readonly List<int> _pow1 = new List<int> { 1 };
// _pow2 = powers of base modulo 2^64
internal readonly List<long> _pow2 = new List<long> { 1L };
internal void EnsureLength(int length)
{
if (_pow1.Capacity < length)
{
_pow1.Capacity = _pow2.Capacity = length;
}
for (int currentIndx = _pow1.Count - 1; currentIndx < length; ++currentIndx)
{
_pow1.Add((int)(_pow1[currentIndx] * _hashBase % _mod));
_pow2.Add(_pow2[currentIndx] * _hashBase);
}
}
}
private class RollingHashedString
{
readonly RollingHashPowers _pows;
readonly int[] _pref1; // Hash on prefix modulo mod
readonly long[] _pref2; // Hash on prefix modulo 2^64
// Constructor from string:
internal RollingHashedString(RollingHashPowers pows, string s, bool caseInsensitive = false)
{
_pows = pows;
_pref1 = new int[s.Length + 1];
_pref2 = new long[s.Length + 1];
const long capAVal = 'A';
const long capZVal = 'Z';
const long aADif = 'a' - 'A';
unsafe
{
fixed (char* c = s)
{
// Fill arrays with polynomial hashes on prefix
for (int i = 0; i < s.Length; ++i)
{
long v = c[i];
if (caseInsensitive && capAVal <= v && v <= capZVal)
{
v += aADif;
}
_pref1[i + 1] = (int)((_pref1[i] + v * _pows._pow1[i]) % RollingHashPowers._mod);
_pref2[i + 1] = _pref2[i] + v * _pows._pow2[i];
}
}
}
}
// Rollingnomial hash of subsequence [pos, pos+len)
// If mxPow != 0, value automatically multiply on base in needed power.
// Finally base ^ mxPow
internal Tuple<int, long> Apply(int pos, int len, int mxPow = 0)
{
int hash1 = _pref1[pos + len] - _pref1[pos];
long hash2 = _pref2[pos + len] - _pref2[pos];
if (hash1 < 0)
{
hash1 += RollingHashPowers._mod;
}
if (mxPow != 0)
{
hash1 = (int)((long)hash1 * _pows._pow1[mxPow - (pos + len - 1)] % RollingHashPowers._mod);
hash2 *= _pows._pow2[mxPow - (pos + len - 1)];
}
return Tuple.Create(hash1, hash2);
}
}
private readonly RollingHashPowers _rhp;
public RollingHash(int longestLength = 0)
{
_rhp = new RollingHashPowers();
if (longestLength > 0)
{
_rhp.EnsureLength(longestLength);
}
}
public string FindCommonSubstring(string a, string b, bool caseInsensitive = false)
{
// Calculate max neede power of base:
int mxPow = Math.Max(a.Length, b.Length);
_rhp.EnsureLength(mxPow);
// Create hashing objects from strings:
RollingHashedString hash_a = new RollingHashedString(_rhp, a, caseInsensitive);
RollingHashedString hash_b = new RollingHashedString(_rhp, b, caseInsensitive);
// Binary search by length of same subsequence:
int pos = -1;
int low = 0;
int minLen = Math.Min(a.Length, b.Length);
int high = minLen + 1;
var tupleCompare = Comparer<Tuple<int, long>>.Default;
while (high - low > 1)
{
int mid = (low + high) / 2;
List<Tuple<int, long>> hashes = new List<Tuple<int, long>>(a.Length - mid + 1);
for (int i = 0; i + mid <= a.Length; ++i)
{
hashes.Add(hash_a.Apply(i, mid, mxPow));
}
hashes.Sort(tupleCompare);
int p = -1;
for (int i = 0; i + mid <= b.Length; ++i)
{
if (hashes.BinarySearch(hash_b.Apply(i, mid, mxPow), tupleCompare) >= 0)
{
p = i;
break;
}
}
if (p >= 0)
{
low = mid;
pos = p;
}
else
{
high = mid;
}
}
// Output answer:
return pos >= 0
? b.Substring(pos, low)
: string.Empty;
}
}

GF(256) finite field multiplication function in C#

I'm implementing AES in C# and at some point (MixColumns function) I have to multiply two Bytes over the GF(2^8) finite field.
So, I have three options:
Use a default function that dotNet has (does it have something like that?)
Write a custom function which does that
Use lookup tables
For the custom function I found a piece of C code which I tried to rewrite for C#, but it doesn't work (I get wrong results). (*)
Here is the original C piece of code (source):
/* Multiply two numbers in the GF(2^8) finite field defined
* by the polynomial x^8 + x^4 + x^3 + x + 1 */
uint8_t gmul(uint8_t a, uint8_t b) {
uint8_t p = 0;
uint8_t counter;
uint8_t hi_bit_set;
for (counter = 0; counter < 8; counter++) {
if (b & 1)
p ^= a;
hi_bit_set = (a & 0x80);
a <<= 1;
if (hi_bit_set)
a ^= 0x1b; /* x^8 + x^4 + x^3 + x + 1 */
b >>= 1;
}
return p;
}
And this is what I rewrote:
public Byte GMul(Byte a, Byte b) { // Galois Field (256) Multiplication
Byte p = 0;
Byte counter;
Byte hi_bit_set;
for (counter = 0; counter < 8; counter++) {
if ((b & 1) != 0) {
p ^= a;
}
hi_bit_set = (Byte) (a & 0x80);
a <<= 1;
if (hi_bit_set != 0) {
a ^= 0x1b; /* x^8 + x^4 + x^3 + x + 1 */
}
b >>= 1;
}
return p;
}
I also found some lookup tables here, and it seemed a simple and fine approach, but I don't really know how to use them, though I got a hunch. (**)
Bottom line: which option should I choose, and how can I make it work, given what I wrote above is all I got so far, and that I don't really want to go very deep with the math knowledge.
UPDATE:
*) Meanwhile I realised my C# rewrote code was producing correct answers, it was just my fault because I messed up when I verified them.
**) The tables can be used as a Byte[256] array, and the answer for, let's say, x*3 is table_3[x], x being converted from HEX to DECIMAL when used as index for the table array.
In order to multiply x * 3 in GF(2), one just accesses x=table_3[x];
There's probably a 3 Look-up-table method available that uses a logarithm approach.
Just as in regular numbers a*b = 2^(log2(a)+log2(b)), the same happens in GF(2), but without floating points or rounding errors.

How to "flatten" or "index" 3D-array in 1D array?

I am trying to flatten 3D array into 1D array for "chunk" system in my game. It's a 3D-block game and basically I want the chunk system to be almost identical to Minecraft's system (however, this isn't Minecraft clone by any measure). In my previous 2D-games I have accessed the flattened array with following algorithm:
Tiles[x + y * WIDTH]
However, this obviously doesn't work with 3D since it's missing the Z-axis. I have no idea how to implement this sort of algorithm in 3D-space. Width, height and depth are all constants (and width is just as large as height).
Is it just x + y*WIDTH + Z*DEPTH ? I am pretty bad with math and I am just beginning 3D-programming so I am pretty lost :|
PS. The reason for this is that I am looping and getting stuff by index from it quite a lot. I know that 1D arrays are faster than multi-dimensional arrays (for reasons I cant remember :P ). Even though this may not be necessary, I want as good performance as possible :)
Here is a solution in Java that gives you both:
from 3D to 1D
from 1D to 3D
Below is a graphical illustration of the path I chose to traverse the 3D matrix, the cells are numbered in their traversal order:
Conversion functions:
public int to1D( int x, int y, int z ) {
return (z * xMax * yMax) + (y * xMax) + x;
}
public int[] to3D( int idx ) {
final int z = idx / (xMax * yMax);
idx -= (z * xMax * yMax);
final int y = idx / xMax;
final int x = idx % xMax;
return new int[]{ x, y, z };
}
The algorithm is mostly the same. If you have a 3D array Original[HEIGHT, WIDTH, DEPTH] then you could turn it into Flat[HEIGHT * WIDTH * DEPTH] by
Flat[x + WIDTH * (y + DEPTH * z)] = Original[x, y, z]
As an aside, you should prefer arrays of arrays over multi-dimensional arrays in .NET. The performance differences are significant
I think the above needs a little correction. Lets say you have a HEIGHT of 10, and a WIDTH of 90, single dimensional array will be 900. By the above logic, if you are at the last element on the array 9 + 89*89, obviously this is greater than 900. The correct algorithm is:
Flat[x + HEIGHT* (y + WIDTH* z)] = Original[x, y, z], assuming Original[HEIGHT,WIDTH,DEPTH]
Ironically if you the HEIGHT>WIDTH you will not experience an overflow, just complete bonkers results ;)
x + y*WIDTH + Z*WIDTH*DEPTH. Visualize it as a rectangular solid: first you traverse along x, then each y is a "line" width steps long, and each z is a "plane" WIDTH*DEPTH steps in area.
You're almost there. You need to multiply Z by WIDTH and DEPTH:
Tiles[x + y*WIDTH + Z*WIDTH*DEPTH] = elements[x][y][z]; // or elements[x,y,z]
TL;DR
The correct answer can be written various ways, but I like it best when it can be written in a way that is very easy to understand and visualize. Here is the exact answer:
(width * height * z) + (width * y) + x
TS;DR
Visualize it:
someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX
someNumberToRepresentZ indicates which matrix we are on (depth). To know which matrix we are on, we have to know how big each matrix is. A matrix is 2d sized as width * height, simple. The question to ask is "how many matrices are before the matrix I'm on?" The answer is z:
someNumberToRepresentZ = width * height * z
someNumberToRepresentY indicates which row we are on (height). To know which row we are on, we have to know how big each row is: Each row is 1d, sized as width. The question to ask is "how many rows are before the row I'm on?". The answer is y:
someNumberToRepresentY = width * y
someNumberToRepresentX indicates which column we are on (width). To know which column we are on we simply use x:
someNumberToRepresentX = x
Our visualization then of
someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX
Becomes
(width * height * z) + (width * y) + x
The forward and reverse transforms of Samuel Kerrien above are almost correct. A more concise (R-based) transformation maps are included below with an example (the "a %% b" is the modulo operator representing the remainder of the division of a by b):
dx=5; dy=6; dz=7 # dimensions
x1=1; y1=2; z1=3 # 3D point example
I = dx*dy*z1+dx*y1+x1; I # corresponding 2D index
# [1] 101
x= I %% dx; x # inverse transform recovering the x index
# [1] 1
y = ((I - x)/dx) %% dy; y # inverse transform recovering the y index
# [1] 2
z= (I-x -dx*y)/(dx*dy); z # inverse transform recovering the z index
# [1] 3
Mind the division (/) and module (%%) operators.
The correct Algorithm is:
Flat[ x * height * depth + y * depth + z ] = elements[x][y][z]
where [WIDTH][HEIGHT][DEPTH]
To better understand description of 3D array in 1D array would be ( I guess Depth in best answer is meant Y size)
IndexArray = x + y * InSizeX + z * InSizeX * InSizeY;
IndexArray = x + InSizeX * (y + z * InSizeY);
m[x][y][z] = data[xYZ + yZ + z]
x-picture:
0-YZ
.
.
x-YZ
y-picture
0-Z
.
.
.
y-Z
summing up, it should be : targetX*YZ + targetY*Z + targetZ
In case, somebody is interested to flatten an nD (2D, 3D, 4D, ...) array to 1D, I wrote the below code. For example, if the size of the array in different dimensions is stored in the sizes array:
# pseudo code
sizes = {size_x, size_y, size_z,...};
This recursive function gives you the series of {1, size_x, size_x*size_y, size_x*size_y*size_z, ...}
// i: number of the term
public int GetCoeff(int i){
if (i==0)
return 1;
return sizes[i-1]*GetCoeff(i-1);
}
So, we have to multiply nD indexes by their corresponding series term and sum them to get {ix + iy*size_x + iz*size_x*size_y, ...}:
// indexNd: {ix, iy, iz, ...}
public int GetIndex1d(int[] indexNd){
int sum =0;
for (var i=0; i<indexNd.Length;i++)
sum += indexNd[i]*GetCoeff(i);
return sum;
}
In this code I assumed, the nD array is contiguous in memory along firstly x, then y, z, ... . So probably you call your array-like arr[z,y,x]. But, if you call them the other way, arr[x,y,z] then z is the fastest index and we like to calculate iz + iy*size_z + ix* size_z*size_y. In this case, the below function gives us the series {1, size_z, size_z*size_y, ...}:
// Dims is dimension of array, like 3 for 3D
public int GetReverseCoeff(int i){
if (i==0)
return 1;
return sizes[Dims-i]*GetReverseCoeff(i-1);
}
The coefficients are stored in the right order:
public void SetCoeffs(){
for (int i=0;i<Dims;i++)
coeffs[Dims-i-1] = GetReverseCoeff(i);
}
The 1D index is calculated the same as before except coeffs array is used:
// indexNd: {ix, iy, iz, ...}
public int GetIndex1d(int[] indexNd){
int sum =0;
for (var i=0; i<indexNd.Length;i++)
sum += indexNd[i]*coeffs[i];
return sum;
}
Samuel Kerrien's answer to python :
def to1D(crds,dims):
x,y,z=crds
xMax,yMax,zMax=dims
return (z * xMax * yMax) + (y * xMax) + x
def to3D(idx,dims):
xMax,yMax,zMax=dims
z = idx // (xMax * yMax)
idx -= (z * xMax * yMax)
y = idx // xMax
x = idx % xMax
return x, y, z

Categories