Converting double to int array - c#

I'm trying to XOR each letter from my TextBox with each value from my array.
The problem is, that when I convert double to int array, my int array result stores only one value.
If I run my code I get first letter XORed, but if I input more then one, I get message :
System.IndexOutOfRangeException: Index was outside the bounds of the array.
I have tried myself to create an int array like: int[] result = new int[] {1,2,3,4,5,6,7}; and I didn't have any problems with XORing up to 7 letters..
private void iTalk_Button_12_Click(object sender, EventArgs e)
{
ambiance_RichTextBox1.Text = XorText(ambiance_RichTextBox1.Text);
}
private string XorText(string text)
{
string newText = "";
double r = 3.9;
double[] first_value = new double[text.Length];
double[] to_int_array = new double[text.Length];
for (int i = 0; i < text.Length; i++)
{
double get_first = r * i * (1 - i);
int index = (int)(i * text.Length);
first_value[index] = get_first;
}
for (int i = 0; i < text.Length; i++)
{
int xnbb = 0;
if (first_value[i] > Math.Exp(Math.Log(2) * (-i)))
{
double get_first = first_value[i] - Math.Exp(Math.Log(2) * (-i));
xnbb = 1;
}
double array_of_values = xnbb + 1 * Math.Round(Math.Exp(Math.Log(2) * (24 - i)));
int index = (int)(i * text.Length);
to_int_array[index] = array_of_values;
int[] result = new int[] { Convert.ToInt32(to_int_array[i]) };
int charValue = Convert.ToInt32(text[i]);
charValue ^= result[i]%320;
newText += char.ConvertFromUtf32(charValue);
}
return newText;
}

double[] first_value = new double[text.Length];
...
for (int i = 0; i < text.Length; i++)
{
double get_first = r * i * (1 - i);
int index = (int)(i * text.Length);
first_value[index] = get_first;
}
When the text length is 2, first_value index may run from 0..1. i will loop from 0 to 1. the calculated index becomes 1 x 2 = 2, and that is beyond the index range.

When passing a string with 2 characters to XorText, the System.IndexOutOfRangeException is thrown in this Line:
first_value[index] = get_first;
because the index is 2 when the loop body is executed the second time:
int index = (int)(i * text.Length);
You really should consider learning how to use a debugger. It will make programming easier.

Related

Calculate values of the spectrum with FFT

I have to calculate the spectrum values of an audio.
I used aForge's FFT in Sources/Math/FourierTransform.cs and I used an example of sampling with 16 samples as used in this video to check the results with excel (I tested the results in a spreadsheet like in the video).
FFT:
public enum Direction
{
Forward = 1,
Backward = -1
};
private const int minLength = 2;
private const int maxLength = 16384;
private const int minBits = 1;
private const int maxBits = 14;
private static int[][] reversedBits = new int[maxBits][];
private static Complex[,][] complexRotation = new Complex[maxBits, 2][];
static void Main(string[] args)
{
var Data = new Complex[16];
Data[0] = new Complex(0, 0);
Data[1] = new Complex((float)0.998027, 0);
Data[2] = new Complex((float)0.125333, 0);
Data[3] = new Complex((float)-0.98229, 0);
Data[4] = new Complex((float)-0.24869, 0);
Data[5] = new Complex((float)0.951057, 0);
Data[6] = new Complex((float)0.368125, 0);
Data[7] = new Complex((float)-0.90483, 0);
Data[8] = new Complex((float)-0.48175, 0);
Data[9] = new Complex((float)0.844328, 0);
Data[10] = new Complex((float)0.587785, 0);
Data[11] = new Complex((float)-0.77051, 0);
Data[12] = new Complex((float)-0.68455, 0);
Data[13] = new Complex((float)0.684547, 0);
Data[14] = new Complex((float)0.770513, 0);
Data[15] = new Complex((float)-0.58779, 0);
FFT(Data, Direction.Forward);
for (int a = 0; a <= Data.Length - 1; a++)
{
Console.WriteLine(Data[a].Re.ToString());
}
Console.ReadLine();
}
public static void FFT(Complex[] data, Direction direction)
{
int n = data.Length;
int m = Tools.Log2(n);
// reorder data first
ReorderData(data);
// compute FFT
int tn = 1, tm;
for (int k = 1; k <= m; k++)
{
Complex[] rotation = GetComplexRotation(k, direction);
tm = tn;
tn <<= 1;
for (int i = 0; i < tm; i++)
{
Complex t = rotation[i];
for (int even = i; even < n; even += tn)
{
int odd = even + tm;
Complex ce = data[even];
Complex co = data[odd];
double tr = co.Re * t.Re - co.Im * t.Im;
double ti = co.Re * t.Im + co.Im * t.Re;
data[even].Re += tr;
data[even].Im += ti;
data[odd].Re = ce.Re - tr;
data[odd].Im = ce.Im - ti;
}
}
}
if (direction == Direction.Forward)
{
for (int i = 0; i < n; i++)
{
data[i].Re /= (double)n;
data[i].Im /= (double)n;
}
}
}
private static int[] GetReversedBits(int numberOfBits)
{
if ((numberOfBits < minBits) || (numberOfBits > maxBits))
throw new ArgumentOutOfRangeException();
// check if the array is already calculated
if (reversedBits[numberOfBits - 1] == null)
{
int n = Tools.Pow2(numberOfBits);
int[] rBits = new int[n];
// calculate the array
for (int i = 0; i < n; i++)
{
int oldBits = i;
int newBits = 0;
for (int j = 0; j < numberOfBits; j++)
{
newBits = (newBits << 1) | (oldBits & 1);
oldBits = (oldBits >> 1);
}
rBits[i] = newBits;
}
reversedBits[numberOfBits - 1] = rBits;
}
return reversedBits[numberOfBits - 1];
}
private static Complex[] GetComplexRotation(int numberOfBits, Direction direction)
{
int directionIndex = (direction == Direction.Forward) ? 0 : 1;
// check if the array is already calculated
if (complexRotation[numberOfBits - 1, directionIndex] == null)
{
int n = 1 << (numberOfBits - 1);
double uR = 1.0;
double uI = 0.0;
double angle = System.Math.PI / n * (int)direction;
double wR = System.Math.Cos(angle);
double wI = System.Math.Sin(angle);
double t;
Complex[] rotation = new Complex[n];
for (int i = 0; i < n; i++)
{
rotation[i] = new Complex(uR, uI);
t = uR * wI + uI * wR;
uR = uR * wR - uI * wI;
uI = t;
}
complexRotation[numberOfBits - 1, directionIndex] = rotation;
}
return complexRotation[numberOfBits - 1, directionIndex];
}
// Reorder data for FFT using
private static void ReorderData(Complex[] data)
{
int len = data.Length;
// check data length
if ((len < minLength) || (len > maxLength) || (!Tools.IsPowerOf2(len)))
throw new ArgumentException("Incorrect data length.");
int[] rBits = GetReversedBits(Tools.Log2(len));
for (int i = 0; i < len; i++)
{
int s = rBits[i];
if (s > i)
{
Complex t = data[i];
data[i] = data[s];
data[s] = t;
}
}
}
These are the results after the transformation:
Output FFT results: Excel FFT results:
0,0418315622955561 0,669305
0,0533257974328085 0,716163407
0,137615673627316 0,908647001
0,114642731070279 1,673453043
0,234673940537634 7,474988602
0,0811255020953362 0,880988382
0,138088891589122 0,406276784
0,0623766891658306 0,248854492
0,0272978749126196 0,204227
0,0124250144575261 0,248854492
0,053787064184711 0,406276784
0,00783331226557493 0,880988382
0,0884368745610118 7,474988602
0,0155431246384978 1,673453043
0,0301093757152557 0,908647001
0 0,716163407
The results are not at all similar. Where is it wrong?
Is the implementation of complex (Data) wrong or is the FFT method wrong or other?
Thanks in advance!
First, the resulting FFT is a complex function in general. You're only displaying the real parts in your code but the thing you're comparing to is displaying the magnitudes, so of course they're going to be different: you're comparing apples to oranges.
When you use magnitudes and compare apples to apples, you should get this:
for (int a = 0; a <= Data.Length - 1; a++)
{
Console.WriteLine(Data[a].Magnitude.ToString());
}
...
0.0418315622955561
0.0447602132472683
0.0567904388057513
0.104590813761862
0.46718679147454
0.0550617784710375
0.025392294285886
0.0155534081359397
0.0127641875296831
0.0155534081359397
0.025392294285886
0.0550617784710375
0.46718679147454
0.104590813761862
0.0567904388057513
0.0447602132472683
That looks a little better -- it has the same symmetry property as the Excel output and there appear to be peaks in the same locations.
It almost looks like the scale is off. If I divide each element by the corresponding element from the Excel output, I get:
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
So your results are pretty much correct, just off by a scaling factor.
You're dividing everything by n in the last step of your FFT:
if (direction == Direction.Forward)
{
for (int i = 0; i < n; i++)
{
data[i].Re /= (double)n;
data[i].Im /= (double)n;
}
}
This is conventionally done for the inverse transform, not the forward transform.
In summary, changing the output from Data[a].Re to Data[a].Magnitude and changing the condition at the end of FFT from if (direction == Direction.Forward) to if (direction == Direction.Backward), I get this output:
0.669304996728897
0.716163411956293
0.908647020892022
1.67345302018979
7.47498866359264
0.880988455536601
0.406276708574176
0.248854530175035
0.20422700047493
0.248854530175035
0.406276708574176
0.880988455536601
7.47498866359264
1.67345302018979
0.908647020892022
0.716163411956293
which matches the Excel output.

Axis Label Value Removal

I have a problem (as seen in the screenshot below) where my chart in Visual C# looks great, but I'd like to remove the first and last axis interval label on the X-Axis (specifically the "3750" and "98250" in my bar chart).
In other words, these two labels shouldn't be visible/show nothing.
Code:
private void btnRun_Click(object sender, EventArgs e)
{
double numIter, PvMean, PvStDev = 0;
int nMin, nMax, numBins = 0;
//NOTE: n is # vehicles sold; numBins is # of bins
numIter = double.Parse(txtNumIter.Text);
numBins = int.Parse(txtNumBins.Text);
PvMean = double.Parse(txtMean.Text);
PvStDev = double.Parse(txtStDev.Text);
nMin = int.Parse(txtMin.Text);
nMax = int.Parse(txtMax.Text);
//+- 3 st devs
PvMin = ((-3) * PvStDev) + PvMean;
PvMax = (3 * PvStDev) + PvMean;
PtMin = nMin * PvMin;
PtMax = nMax * PvMax;
//Bin array
int [] Bins = new int[numBins+1];
Random nPv = new Random();
double Pt, totalprofit = 0;
int Pv, n = 0;
int i = 0;
for(i=0; i < numIter ; i++)
{
//Use these vars to be able to produce random numbers
int PvMinRand = Convert.ToInt32(PvMin);
int PvMaxRand = Convert.ToInt32(PvMax);
n = nPv.Next(nMin, (nMax + 1));
Pv = nPv.Next(PvMinRand, (PvMaxRand + 1));
//Equation for random Pv and n to get Pt
Pt = n * Pv;
//Increments total profit;
totalprofit += Pt;
//Bin index from rand
int index = 0;
//Call GetBinIndex method
index = GetBinIndex(PtMin, PtMax, numBins, Pt);
//Incremenents bin count by 1
Bins[index] += 1;
}
//Increment of chart
double Increment, incrCount, binRange = 0;
binRange = PtMax - PtMin;
Increment = binRange / numBins;
chtSim.ChartAreas[0].AxisX.Interval = Increment;
//Graph bars for each bin loop
int j = 1;
for (j = 1; j < (numBins+1); j++)
{
//Increases incr label value for each iteration above Pt Min
incrCount = Increment * j + PtMin;
//Graph bar for each index
chtSim.Series[0].Points.AddXY(incrCount, Bins[j]);
}
You can set the AxisLabel individually for each DataPoint.
By doing so, the automatic labels get removed. So you can write.:
int ix = chtSim.Series[0].Points.AddXY(incrCount, Bins[j]);
chtSim.Series[0].Points[ix].AxisLabel = incrCount;
.. in your loop.
Now only those labels you have set yourself are shown.

Float array resampling

I want to "stretch" a one-dimensional float array into a bigger array.
//expected behaviour
float[] initialArray = {2.0, 6.5, 2.0}
float[] biggerArray = resample(initialArray, 7 /*new size*/)
//output: {2.0, 3.5, 5.0, 6.5, 5.0, 3.5, 2.0}
The new values should propobaly be calculated from linear interpolation of the previous array values but i can't figure out how to achieve that.
Any hint ?
Lets the length of a source array is N, and the length of a destination array is M where N < M and N > 1.
You can calculate the new index of the source i-th element by the formula:
j = i * (M - 1)/(N - 1);
When i == 0 then j == 0; and when i == N - 1 then j == M - 1. The external loop can looks like this:
float[] source = ...;
float[] destination = ...;
destination[0] = source[0];
for (int i = 1; i < source.Length; i++)
{
int j = i * (destination.Length - 1)/(source.Length - 1);
destination[j] = source[i];
// interpolation
}
To interpolation you should calculate intermediate values for each pair (source[i - 1], source[i]). You'll need to store previous value of j:
destination[0] = source[0];
int jPrevious = 0;
for (int i = 1; i < source.Length; i++)
{
int j = i * (destination.Length - 1)/(source.Length - 1);
Interpolate(destination, jPrevious, j, source[i - 1], source[i]);
jPrevious = j;
}
private static void Interpolate(float[] destination, int destFrom, int destTo, float valueFrom, float valueTo)
{
int destLength = destTo - destFrom;
float valueLength = valueTo - valueFrom;
for (int i = 0; i <= destLength; i++)
destination[destFrom + i] = valueFrom + (valueLength * i)/destLength;
}
This one works for both if source size is larger than destination and vice versa.
private double[] Resample(double[] source, int n)
{
//n destination length
int m = source.Length; //source length
double[] destination = new double[n];
destination[0] = source[0];
destination[n-1] = source[m-1];
for (int i = 1; i < n-1; i++)
{
double jd = ((double)i * (double)(m - 1) / (double)(n - 1));
int j = (int)jd;
destination[i] = source[j] + (source[j + 1] - source[j]) * (jd - (double)j);
}
return destination;
}
You can use List<float>:
float[] initialArray = { 2.0f, 6.5f, 2.0f };
List<float> initialArrayTemp = ToListFloat(initialArray);
private List<float> ToListFloat(float[] array)
{
List<float> list = new List<float>();
for (int i = 0; i < array.Length; i++)
{
list.Add(array[i]);
}
return list;
}
Now your array is a dynamic array and you can add your new nodes anywhere of your Array by using Insert() method.
As soon as you need a new static array, use below:
float[] newInitialArray = initialArrayTemp.ToArray();

How to parameterize a method with a given dimension during multidimensional array iteration?

I have a function which is applied on each element of a 2D array (double[,]), but only along a given dimension.
I had to create two functions because I don't know how to pass the desired dimension to the method as a parameter. I ended up with a "vertical_foo" and a "horizontal_foo" functions, which are almost identical to each other:
private double[,] vertical_foo (double[,] a) {
int height = a.GetLength(0);
int width = a.GetLength(1);
var result = new double[height, weight];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// Here I use first ("i") dimension
int before = Math.Max(i-1, 0);
int after = Math.Min(i+1, height-1);
result[i,j] = (a[after, j] - a[before, j]) * 0.5;
}
}
return result;
}
private double[,] horizontal_foo (double[,] a) {
int height = a.GetLength(0);
int width = a.GetLength(1);
var result = new double[height, weight];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// Here I use second ("j") dimension
int before = Math.Max(j-1, 0);
int after = Math.Min(j+1, height-1);
result[i,j] = (a[i, after] - a[i, before]) * 0.5;
}
}
return result;
}
I would like to have a signature like this, where the second parameter is the dimension on which I want to apply the indexing:
private double[,] general_foo (double[,] a, int dimension) {}
Any suggestion is much welcome!
I'll take a stab at this:
private double[,] general_foo(double[,] a, int dimension)
{
var w = a.GetLength(0);
var h = a.GetLength(1);
var result = new double[w, h];
var otherDimension = 1 - dimension; // NOTE only works for 2D arrays
var otherDimensionLength = a.GetLength(otherDimension);
var dimensionLength = a.GetLength(dimension);
for (int i = 0; i < dimensionLength; i++)
{
for (int j = 0; j < otherDimensionLength; j++)
{
var setIndexes = new int[2] { j, j };
setIndexes[dimension] = i;
var beforeIndexes = new int[2] { j, j };
beforeIndexes[dimension] = Math.Max(i - 1, 0);
var afterIndexes = new int[2] { j, j };
afterIndexes[dimension] = Math.Min(i + 1, dimensionLength - 1);
var beforeValue = (double)a.GetValue(beforeIndexes);
var afterValue = (double)a.GetValue(afterIndexes);
result.SetValue((afterValue - beforeValue) * 0.5, setIndexes);
}
}
return result;
}
Here's a more generic method. It uses a few lambdas, so the it might also help you understand the use of lambdas a bit also.
// Iterates through every item in a multidementional array array
private Array MutateArray<T>(Array a, Func<T, int[], T> selector)
{
var rank = a.Rank;
var lengths = Enumerable.Range(0, a.Rank)
.Select(r => a.GetLength(r))
.ToArray(); // Get length of a in each dimension
var result = Array.CreateInstance(typeof(T), lengths);
var index = new int[a.Rank];
foreach (T item in a) // flattens array
{
result.SetValue(selector(item, index), index);
// Get next index value (I'm sure this could be improved)
for (var d = 0; d < rank; d++)
{
if (index[d] == lengths[d] - 1)
{
index[d] = 0;
}
else
{
index[d]++;
break;
}
}
}
return result;
}
// Your "foo" method
private double[,] generic_foo(double[,] a, int d)
{
var upperD = a.GetUpperBound(d);
return (double[,])MutateArray<double>(a, (x, i) =>
{
var prev = i.ToArray(); // clone
prev[d] = Math.Max(prev[d] - 1, 0);
var next = i.ToArray(); // clone
next[d] = Math.Min(next[d] + 1, upperD);
var prevVal = (double)a.GetValue(prev);
var nextVal = (double)a.GetValue(next);
return (nextVal - prevVal) * 0.5;
});
}
Would it be acceptable to do something along these lines?
int before_i = i, after_i = i;
int before_j = j, after_j = j;
switch( dimension ) {
case 0:
before_i = Math.max(i-1,0);
after_i = Math.min(i+1, width-1);
break;
case 1:
before_j = Math.max(j-1,0);
after_j = Math.min(j+1, height-1);
break;
}
result[ i, j ] = (a[after_i, after_j] - a[before_i,before_j]) * 0.5
It's not terribly pretty, but at least this way you don't need two functions.
You could pass in a delegate to extract the dimension you're interested in? (or a lambda)
Func<int[,],int,int[]> accessor here indicates the signature of a function (where the last template parameter is the return type)
private void Working()
{
DoSomething(GetRow,1);
}
So, in this example, you want the "DoSomething" worker to work on a row.
private void DoSomething(Func<int[,],int,int[]> accessor, int Idx)
{
int[,] theData = {{1,1,1,1,1},{2,2,2,2,2}};
int[] someData = accessor(theData,Idx);
}
public int[] GetRow(int[,] data,int index)
{
List<int> numbers = new List<int>();
for (int i = 0; i < data.GetLength(1); i++)
{
numbers.Add(data[index, i]);
}
return numbers.ToArray();
}
In the above example, you get a one dimensional array of 2,2,2,2,2
I'm addressing the general case of extracting a particular part of a multidimensional array here... The method/ lambda you pass in extracts the meaningful part of data...

Help needed in finding coordinate count

I have an 8 X 8 matrix. Now, The below coordinates are occupied
{ 6, 3 }, { 5, 5 }, { 3, 3 }.... What needs to be done is that, I need to build straight line
through these points and needs to count how many coordinates they have touched?
My program so far stands as
private static void GetCount(int[,] Positions)
{
int rcount = 8;
int firstRow = Positions[0, 0];
for (int i = 1; i < Positions.Length/2; i++)
{
int currentRow = Positions[i, 0];
if (currentRow != firstRow)
{
rcount += 8;
firstRow = currentRow;
}
}
int cCount = 8;
int firstCol = Positions[0, 1];
for (int i = 1; i < Positions.Length / 2; i++)
{
int currentCol = Positions[i, 1];
if (currentCol != firstCol)
{
cCount += 8;
firstCol = currentCol;
}
}
int totalCount = rcount - cCount;
Console.WriteLine(totalCount);
}
And I am invoking it as
GetCount(new int[,] { { 6, 3 }, { 5, 5 }, { 3, 3 } });
The output will be 40 here. (count will be 24 for each 3 unique rows i.e. 6,5,3 and count will be 16 for 2 unique columns i.e. 3 and 5... So, the total count is 24+16 = 40)
But I am getting the output as 48.
Also is it possible to do the porgram using one single loop?
I am using C# 1.0
Edited
This does work
List<int> lstRows = new List<int>();
List<int> lstCols = new List<int>();
int count = 0;
//Get the unique rows and columns
for (int i = 0; i < marinePositions.Length / 2; i++)
{
if (!lstRows.Contains(marinePositions[i, 0])) lstRows.Add(Positions[i, 0]);
if (!lstCols.Contains(marinePositions[i, 1])) lstCols.Add(Positions[i, 1]);
}
//get row count
for (int i = 0; i < lstRows.Count; i++) count += 8;
//get column count
for (int i = 0; i < lstCols.Count; i++) count += 8;
Console.WriteLine(count);
But need a much better one.. if possible using linq/lambda and no loop
Please help
Here u go... but this in is LINQ and not C# 1.0 which is way too old.. not sure why are you using such old version of the language:
private static void GetCount(int[,] Positions)
{
List<int> x = new List<int>();
List<int> y = new List<int>();
for (int i = 0; i < Positions.Length/2; i++)
{
x.Add(Positions[i, 0]);
y.Add(Positions[i, 1]);
}
int result = (x.Distinct().Count() * 8) + (y.Distinct().Count() * 8);
Console.WriteLine(result);
}
No loops magic:
private static void GetCount(int[,] Positions)
{
var range = Enumerable.Range(0, Positions.Length / 2);
var result = (range.Select(i => Positions[i, 0]).Distinct().Count() * 8) +
(range.Select(i => Positions[i, 1]).Distinct().Count() * 8);
Console.WriteLine(result);
}
CORRECTIONS:
1-
int cCount = 8;
To:
int cCount = 0;
2-
int totalCount = rcount - cCount;
To:
int totalCount = rcount + cCount;
The program should work fine now.

Categories

Resources