Avoid IndexOutOfRangeException by looping back to start of array - c#

I have a array [4,4] that I am looping through and printing values.
trainingpatterns.array = new int[4, 4];
for (int i = 0; i < 4; i++)
{
var element1 = x + array.coordinates[0];
var element2 = x + array.coordinates[2];
var element3 = x + array.coordinates[4];
var element4 = x + array.coordinates[6];
for (int j = 0; j < 4; j++)
{
var element1 = y + array.coordinates[1];
var element2 = y + array.coordinates[3];
var element3 = y + array.coordinates[5];
var element4 = y + array.coordinates[7];
Console.WriteLine(trainingpatterns.array[element2, element6]);
However my loop requires me to go over the index. So when it gets to [5,4] for example the exception will be thrown.
What I want to do is if the x value goes out of bounds, for it to loop back to the start. So for example [5,4] will print [0,4] or [6,4] will print [2,4].
I have tried using a try catch but I cannot make the function universal for all values.
Thank you.

I suspect you just want to use the % operator:
int length0 = inputArray.GetUpperBound(0);
int length1 = inputArray.GetUpperBound(1);
...
var value = inputArray[x % length0, y % length1];
Note that this will not wrap negative numbers, however - the range of a % b is (-b, +b), whereas you want [0, +b). Taking account of this is a bit more longwinded, but let me know if you need it. If your index values will always be non-negative, you don't need to worry about it.

Related

Curve fitting to a 3D polynomial with variable powers

I have 3 data sets. 2 for polynomial itself (let's call them x and y) and 1 for the function value (it's gonna be z).
Polynomial looks something like this (assuming the power of both dimensions is 3):
z = a00 + a01*x + a02*x^2 + a03*x^3 + a10*y + a11*y*x + a12*y*x^2 ... etc
I need to be able to set the power of each dimension when preparing for approximation of values of "a".
I don't really get how CurveFitting functions work with Math.NET Numerics, but i've tried Fit.LinearMultiDim and MultipleRegression.QR. I'm having trouble with initializing the Func delegate
var zs = new double[]
{
//values here
};
var x = new double[]
{
//values here
};
var y = new double[]
{
//values here. But the amounts are equal
};
var design = Matrix<double>.Build.DenseOfRowArrays(Generate.Map2(x, y,(t, w) =>
{
var list = new List<double>(); //Can i get this working?
for (int i = 0; i <= 3; i++)
{
for (int j = 0; j <= 3; j++)
{
list.Add(Math.Pow(t, j)*Math.Pow(w, i));
}
}
return list.ToArray();
}));
double[] p = MultipleRegression.QR(design, Vector<double>.Build.Dense(zs)).ToArray();
So ideally i need to be able to compose the function with some sort of loop that accounts for the max power of both variables.
UPD: The function is always above zero on any axis
I think i got it working.
Here's the code:
List<Func<double[], double>> ps = new List<Func<double[],double>>();
for (int i = 0; i <= polynomialOrderFirstVal; i++)
{
for (int j = 0; j <= polynomialOrderSecVal; j++)
{
var orderFirst = j;
var orderSecond = i;
ps.Add(d => Math.Pow(d[0], orderFirst) * Math.Pow(d[1],orderSecond));
}
}
var psArr = ps.ToArray();
double[] coefs = Fit.LinearMultiDim(x, y, psArr);

system.IndexOutOfRange exception in C# [duplicate]

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 5 years ago.
I know this kind of question is asked before, but I am a noob and cannot understand where the array is out of bounds.
P.S this is not the exact duplicate of the every " system.IndexOutOfRange exception in C# " as the situation and the context of the problem is totally different from each other.So please read the question first before reporting it as the " exact duplicate ".
class Program
{
static void Main(string[] args)
{
int highestcount = 0, e = 0, h = 0;
string highest = "", a = "", b = "", j = "";
int y = int.Parse(Console.ReadLine());
e = y - 1;
string[] savArray = new string[e];
for (int count = 0; count < y; count++)
{
var x = Console.ReadLine().Split(' ');
if (count+1 <= y)
{
j = x[count + 1];
savArray[count] = j;
}
}
for (int count1 = 0; count1 < y; count1++)
{
h = 0;
a = savArray[count1];
for (int count2 = 1; count2 < y; count2++)
{
b = savArray[ count2];
if (a == b)
{
h = h + 1;
if (highestcount <= h)
{
highestcount = h;
highest = a;
}
}
}
}
Console.Write(highest);
Console.Read();
}
}
The program is to find the most common sport.
First, the user has to enter how many no: of entries are there on the list.
After that, the user has to enter his name and then his favorite sport.
If you read the program what I meant to do is simply save the 2nd value of x in the array because every second value is the sport which the user has given, as I want to save the sport's name to check which sport is more common.
But the exception is ruining the simple idea and I am stuck with it, please help.
Let's say that savArray has 1 element.
Then you do this:
var x = Console.ReadLine().Split(' ');
//Let's say x is "X" which is creates an array of size 1
if (count + 1 <= y) <----this is true (0+1<=1)
{
j = x[count + 1]; <----- BOOM x[1] when x has only one element.
for (int count = 0; count < y; count++)
{
var x = Console.ReadLine().Split(' ');
if (count+1 <= y)
{
j = x[count + 1];
savArray[count] = j;
}
}
Haven't double checked but...
[count + 1]
Given the for loop constraints (count < y)
the maximum possible value for count is y - 1...
but....
count + 1 when count = y -1... and thus is out of range... I think. Again. Haven't double checked.

Microsoft.Office.Interop IndexOutOfRangeException

The below IndexOutOfRangeException is not letting my code run (it compiles). While I understand this kind of exception (array indexes etc) the issue is, what I am trying to do is simply update the String subsection2 with the value in cell B[excelrow]. For some reason, there is an index out of bounds exception which to me does not make sense. Neither subsection2 or excelrow is part of an array. The only array I can think of is the excel array, but excelrow is an integer with value of 3, it should updated to row B3, and so on. (I've even tried updating with B3 directly and I get the same error).
To help you out further with context, this method called createsource takes as input the excel spreadsheet and the total rows in that sheet. It does the below code to output a 2D array containing in the first dimension the excel index of each new order (each different customer), and the 2nd dimension is the number of items ordered per customer.
The method for the code is below:
private int[,] createsource(Microsoft.Office.Interop.Excel.Worksheet xlWorksheet, int totalRows)
{
String subsection = "";
object subsection2 = "";
int orders = 0;
//figures out how many different pages there are going to be
for (int n = 3; n < totalRows + 1; n++)
{
if (!(xlWorksheet.get_Range("B" + n.ToString()).Text == subsection))
{
subsection = xlWorksheet.get_Range("B" + n.ToString()).Text;
orders++;
}
}
MessageBox.Show(orders.ToString());
int[,] source = new int[orders, 2];
int excelrow = 3;
subsection2 = xlWorksheet.get_Range("B" + excelrow.ToString()).Text;
int i;
for (i = 0; i < orders + 1; i++)
{
int j = 1;
if (excelrow == totalRows + 1)
{
break;
}
//Out of bounds exception is found in the below if statement updating subsection2:
if (!(xlWorksheet.get_Range("B" + excelrow.ToString()).Text == subsection2))
{
source[i, 0] = excelrow;
//MessageBox.Show(xlWorksheet.get_Range("B" + excelrow.ToString()).Text.ToString());
subsection2 = xlWorksheet.get_Range("B" + excelrow.ToString()).Text;
excelrow++;
}
for (int iter = 0; iter < 1;)
{
if (excelrow == totalRows + 1)
{
break;
}
if (xlWorksheet.get_Range("B" + excelrow.ToString()).Text == subsection2)
{
excelrow++;
j++;
}
if (!(xlWorksheet.get_Range("C" + excelrow.ToString()).Text == subsection2))
{
subsection2 = xlWorksheet.get_Range("C" + excelrow.ToString()).Text;
iter = 1;
}
}
source[i, 1] = j;
}
MessageBox.Show(source[2, 0].ToString());
return source;
}
I see the problem. You're declaring source as:
int[,] source = new int[orders, 2];
... okay, but look at your loop:
for (i = 0; i < orders + 1; i++)
... which later feeds into:
source[i, 0] = excelrow;
Okay, so if orders = 100, you've declared a 100 long array, going from 0-99. Then your loop, you go from 0 to "less than 100+1", aka 0-100. When you get to the last loop, you're using a value of i=100, and trying to put it into the array spot that doesn't exist.
You need to either decrease your loop by one, or increase your array size by 1.

Finding Offset using double array and list C#

Im trying to find the offset(difference between the array elements) of an array of double..The formula for my offset calculation is Offset= ((double[x+1]-double[x])*33)..
The problem I encounter is I cant seem to display the offsetX. What am I doing wrong here ?
Is there an easier way to do this ?
Here are my codes :
//double[] test is an infinite array containing double values that are passed from the Client to Server via UDP
//example : double[] test={1.11,2.344,3.45,4.54,....,......,....}
//Partial codes on the Server side to calculate and display offset
List<double> array = new List<double>();
//Im trying to store just the elements of postion 0,3,6..from the double []test into list array
//ignore array1[] and array2[]
for (int j = 0; j < test.Length;)
{
array.Add(test[j]); j++;
array1.Add(test[j]); j++;
array2.Add(test[j]); j++;
}
double[] gg = array.ToArray();
//Finding the offset
for (int i = 0, j = 1; i < gg.Length - 1; i++, j++)
{
offsetX.Add(gg[j] - gg[i]);
offsetX[i] = Math.Round(offsetX[i], 1);
offsetX[i] = (offsetX[i] * 33);
}
Console.Write( "OffsetX:" + string.Join(",", offsetX) +"/n");
The method below just iterates over the arrays adding the offsets during the initial iteration of the list
List<double> array = new List<double>() { 1.11,2.344,3.45,4.54 };
var offsets = new List<double>();
for (int i = 1; i < array.Count; i++)
offsets.Add(array[i] - array[i-1]);
This results in the offsets of:
Offsets: 1.234,1.106,1.09

Damerau–Levenshtein distance algorithm, disable counting of delete

How can i disable counting of deletion, in this implementation of Damerau-Levenshtein distance algorithm, or if there is other algorithm already implemented please point me to it.
Example(disabled deletion counting):
string1: how are you?
string2: how oyu?
distance: 1 (for transposition, 4 deletes doesn't count)
And here is the algorithm:
public static int DamerauLevenshteinDistance(string string1, string string2, int threshold)
{
// Return trivial case - where they are equal
if (string1.Equals(string2))
return 0;
// Return trivial case - where one is empty
if (String.IsNullOrEmpty(string1) || String.IsNullOrEmpty(string2))
return (string1 ?? "").Length + (string2 ?? "").Length;
// Ensure string2 (inner cycle) is longer_transpositionRow
if (string1.Length > string2.Length)
{
var tmp = string1;
string1 = string2;
string2 = tmp;
}
// Return trivial case - where string1 is contained within string2
if (string2.Contains(string1))
return string2.Length - string1.Length;
var length1 = string1.Length;
var length2 = string2.Length;
var d = new int[length1 + 1, length2 + 1];
for (var i = 0; i <= d.GetUpperBound(0); i++)
d[i, 0] = i;
for (var i = 0; i <= d.GetUpperBound(1); i++)
d[0, i] = i;
for (var i = 1; i <= d.GetUpperBound(0); i++)
{
var im1 = i - 1;
var im2 = i - 2;
var minDistance = threshold;
for (var j = 1; j <= d.GetUpperBound(1); j++)
{
var jm1 = j - 1;
var jm2 = j - 2;
var cost = string1[im1] == string2[jm1] ? 0 : 1;
var del = d[im1, j] + 1;
var ins = d[i, jm1] + 1;
var sub = d[im1, jm1] + cost;
//Math.Min is slower than native code
//d[i, j] = Math.Min(del, Math.Min(ins, sub));
d[i, j] = del <= ins && del <= sub ? del : ins <= sub ? ins : sub;
if (i > 1 && j > 1 && string1[im1] == string2[jm2] && string1[im2] == string2[jm1])
d[i, j] = Math.Min(d[i, j], d[im2, jm2] + cost);
if (d[i, j] < minDistance)
minDistance = d[i, j];
}
if (minDistance > threshold)
return int.MaxValue;
}
return d[d.GetUpperBound(0), d.GetUpperBound(1)] > threshold
? int.MaxValue
: d[d.GetUpperBound(0), d.GetUpperBound(1)];
}
public static int DamerauLevenshteinDistance( string string1
, string string2
, int threshold)
{
// Return trivial case - where they are equal
if (string1.Equals(string2))
return 0;
// Return trivial case - where one is empty
// WRONG FOR YOUR NEEDS:
// if (String.IsNullOrEmpty(string1) || String.IsNullOrEmpty(string2))
// return (string1 ?? "").Length + (string2 ?? "").Length;
//DO IT THIS WAY:
if (String.IsNullOrEmpty(string1))
// First string is empty, so every character of
// String2 has been inserted:
return (string2 ?? "").Length;
if (String.IsNullOrEmpty(string2))
// Second string is empty, so every character of string1
// has been deleted, but you dont count deletions:
return 0;
// DO NOT SWAP THE STRINGS IF YOU WANT TO DEAL WITH INSERTIONS
// IN A DIFFERENT MANNER THEN WITH DELETIONS:
// THE FOLLOWING IS WRONG FOR YOUR NEEDS:
// // Ensure string2 (inner cycle) is longer_transpositionRow
// if (string1.Length > string2.Length)
// {
// var tmp = string1;
// string1 = string2;
// string2 = tmp;
// }
// Return trivial case - where string1 is contained within string2
if (string2.Contains(string1))
//all changes are insertions
return string2.Length - string1.Length;
// REVERSE CASE: STRING2 IS CONTAINED WITHIN STRING1
if (string1.Contains(string2))
//all changes are deletions which you don't count:
return 0;
var length1 = string1.Length;
var length2 = string2.Length;
// PAY ATTENTION TO THIS CHANGE!
// length1+1 rows is way too much! You need only 3 rows (0, 1 and 2)
// read my explanation below the code!
// TOO MUCH ROWS: var d = new int[length1 + 1, length2 + 1];
var d = new int[2, length2 + 1];
// THIS INITIALIZATION COUNTS DELETIONS. YOU DONT WANT IT
// or (var i = 0; i <= d.GetUpperBound(0); i++)
// d[i, 0] = i;
// But you must initiate the first element of each row with 0:
for (var i = 0; i <= 2; i++)
d[i, 0] = 0;
// This initialization counts insertions. You need it, but for
// better consistency of code I call the variable j (not i):
for (var j = 0; j <= d.GetUpperBound(1); j++)
d[0, j] = j;
// Now do the job:
// for (var i = 1; i <= d.GetUpperBound(0); i++)
for (var i = 1; i <= length1; i++)
{
//Here in this for-loop: add "%3" to evey term
// that is used as first index of d!
var im1 = i - 1;
var im2 = i - 2;
var minDistance = threshold;
for (var j = 1; j <= d.GetUpperBound(1); j++)
{
var jm1 = j - 1;
var jm2 = j - 2;
var cost = string1[im1] == string2[jm1] ? 0 : 1;
// DON'T COUNT DELETIONS! var del = d[im1, j] + 1;
var ins = d[i % 3, jm1] + 1;
var sub = d[im1 % 3, jm1] + cost;
// Math.Min is slower than native code
// d[i, j] = Math.Min(del, Math.Min(ins, sub));
// DEL DOES NOT EXIST
// d[i, j] = del <= ins && del <= sub ? del : ins <= sub ? ins : sub;
d[i % 3, j] = ins <= sub ? ins : sub;
if (i > 1 && j > 1 && string1[im1] == string2[jm2] && string1[im2] == string2[jm1])
d[i % 3, j] = Math.Min(d[i % 3, j], d[im2 % 3, jm2] + cost);
if (d[i % 3, j] < minDistance)
minDistance = d[i % 3, j];
}
if (minDistance > threshold)
return int.MaxValue;
}
return d[length1 % 3, d.GetUpperBound(1)] > threshold
? int.MaxValue
: d[length1 % 3, d.GetUpperBound(1)];
}
here comes my explanation why you need only 3 rows:
Look at this line:
var d = new int[length1 + 1, length2 + 1];
If one string has the length n and the other has the length m, then your code needs a space of (n+1)*(m+1) integers. Each Integer needs 4 Byte. This is waste of memory if your strings are long. If both strings are 35.000 byte long, you will need more than 4 GB of memory!
In this code you calculate and write a new value for d[i,j]. And to do this, you read values from its upper neighbor (d[i,jm1]), from its left neighbor (d[im1,j]), from its upper-left neighbor (d[im1,jm1]) and finally from its double-upper-double-left neighbour (d[im2,jm2]). So you just need values from your actual row and 2 rows before.
You never need values from any other row. So why do you want to store them? Three rows are enough, and my changes make shure, that you can work with this 3 rows without reading any wrong value at any time.
I would advise not rewriting this specific algorithm to handle specific cases of "free" edits. Many of them radically simplify the concept of the problem to the point where the metric will not convey any useful information.
For example, when substitution is free the distance between all strings is the difference between their lengths. Simply transmute the smaller string into the prefix of the larger string and add the needed letters. (You can guarantee that there is no smaller distance because one insertion is required for each character of edit distance.)
When transposition is free the question reduces to determining the sum of differences of letter counts. (Since the distance between all anagrams is 0, sorting the letters in each string and exchanging out or removing the non-common elements of the larger string is the best strategy. The mathematical argument is similar to that of the previous example.)
In the case when insertion and deletion are free the edit distance between any two strings is zero. If only insertion OR deletion is free this breaks the symmetry of the distance metric - with free deletions, the distance from a to aa is 1, while the distance from aa to a is 1. Depending on the application this could possibly be desirable; but I'm not sure if it's something you're interested in. You will need to greatly alter the presented algorithm because it makes the mentioned assumption of one string always being longer than the other.
Try to change var del = d[im1, j] + 1; to var del = d[im1, j];, I think that solves your problem.

Categories