Index out of range for multi dimensional array - c#

I'm getting the error that the index for my array is out of range.
I define a 3D array like this:
Button[, ,] posAr_ItemManager = new Button[maxRows, maxColumns, maxCategories];
Where maxRows, maxColumns and maxCategories are all constant integers.
I then want to loop through this whole array, i do it using nested loops as shown here:
for (int i = 0; i < posAr_ItemManager.GetLength(0); i++)
{
for (int j = 0; i < posAr_ItemManager.GetLength(1); j++)
{
for (int z = 0; i < posAr_ItemManager.GetLength(2); z++)
{
if (posAr_ItemManager[i,j,z] != null)
{
Button but = posAr_ItemManager[i, j, z];
but.Width = itemWidth;
but.Height = itemHeight;
but.SetValue(Canvas.LeftProperty, itemPanelX + (i + 1) * butSpacing + i * itemWidth);
but.SetValue(Canvas.TopProperty, itemPanelY + (i+1)*butSpacing + i* itemHeight);
}
}
}
}
When I run the program it gives the out of range error where I check if the item is not equal to null.
I have no idea why it does it as I thought my declaration of the 3D array is correct and the nested loop as well? thanks in advance!

for (int i = 0; i < posAr_ItemManager.GetLength(0); i++)
{
for (int j = 0; j < posAr_ItemManager.GetLength(1); j++)
{
for (int z = 0; z < posAr_ItemManager.GetLength(2); z++)
look very carefully at the middle tests. Also, consider hoisting the GetLength tests so you only do them once per dimension. Perhaps:
int rows = posAr_ItemManager.GetLength(0), columns = posAr_ItemManager.GetLength(1),
categories = posAr_ItemManager.GetLength(2);
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
for (int cat = 0; cat < categories; cat++)

You're using "i" to check if the loop is over in each of the dimensions. Change it to corresponded i,j,z.
for (int i = 0; i < posAr_ItemManager.GetLength(0); i++)
{
for (int j = 0; **j** < posAr_ItemManager.GetLength(1); j++)
{
for (int z = 0; **z** < posAr_ItemManager.GetLength(2); z++)

Related

Index Out Of Range Bucket Sort

So I wrote bucket sort implementation (I use rnd.NextDouble() to fill my array, so all the elements are in the range between 0 and 1). And I have number of experiments (10 experiments for each array size) and different array sizes (I start with 1000 and then +1000, etc. till 300.000). And sometimes it works fine, but sometimes it gives me OutOfRange exception:
public static void BucketSortImplement(ref int countOfElements, ref float[] array)
{
List<float>[] buckets = new List<float>[countOfElements];
for (int i = 0; i < countOfElements; i++)
{
buckets[i] = new List<float>();
}
for (int i = 0; i < countOfElements; i++)
{
float indexOfElement = array[i] * countOfElements;
buckets[(int)indexOfElement].Add(array[i]); // right here
}
for (int i = 0; i < countOfElements; i++)
{
for (int j = 0; j < buckets[i].Count; j++)
{
float keyElement = buckets[i][j];
int k = j - 1;
while (k >= 0 && buckets[i][k] > keyElement)
{
buckets[i][k + 1] = buckets[i][k];
k -= 1;
}
buckets[i][k + 1] = keyElement;
}
}
int arrayIndex = 0;
for (int i = 0; i < countOfElements; i++)
{
for (int j = 0; j < buckets[i].Count; j++)
{
array[arrayIndex++] = buckets[i][j];
}
}
}
I am a bit confused, because the algorithm itself looks fine, that is I have to calculate array[i] * countOfElements to get the index where I can put my element. Could you please direct me?
If you array contain value '1' it will lead to OutOfRange, because if you have a size of the list equal to 3 (for example) then valid indexes will be in the range [0, 2].

In C#, How can I iterate through a entire 2D Array and count the number of 0s?

I've been trying to iterate through an entire 2D array and count the number of 0s. How can I do this?
I'm sure I have to use the following to make the program work:
Use an outer for loop to iterate through the rows of the array
Use an inner for loop to iterate through the columns of the array
if matrix[row,col] == 0, increment a variable
To get the number of rows of the 2D array, use the method matrix.GetLength(0), and to get the number of columns of the array, use the method matrix.GetLength(1)
Here's what I have attempted so far:
public int Test9(int[,] matrix)
{
int b = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); i++)
{
b = matrix[i, j];
}
}
This is how you can do it..
public int Test9(int[,] matrix)
{
int zeroCounter = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
{
if(matrix[i, j] == 0)
{
zeroCounter++;
}
}
}

Filling matrix with for loops

Firstly, I fill the array with "0"s and then want to replace the first row with "1"s. Can not understand why the 2nd "for" loop fills the whole matrix with "1"s.
int i, j, array[length][width];
for (i = 0; i < length; i++) {
for (j = 0; j < width; j++) {
array[i][j] = 0;
}
}
for (i = 0; i < width; i++) {
array[0][i] = 1;
}`
I ran the code and it only filled the first row of the matrix with 1's. Try running it again.

How can I use hopfield network to learn more patterns?

Is there any relation between number of neurons and ability of Hopfield network to recognize patterns?
I write neural network program in C# to recognize patterns with Hopfield network. My network has 64 neurons. When I train network for 2 patterns, every things work nice and easy, but when I train network for more patterns, Hopfield can't find answer!
So, according to my code, how can I use Hopfield network to learn more patterns?
Should I make changes in this code?
There is my train() function:
public void Train(bool[,] pattern)
{
//N is number of rows in our square matrix
//Convert input pattern to bipolar
int[,] PatternBipolar = new int[N, N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
if (pattern[i, j] == true)
{
PatternBipolar[i, j] = 1;
}
else
{
PatternBipolar[i, j] = -1;
}
}
//convert to row matrix
int count1 = 0;
int[] RowMatrix = new int[(int)Math.Pow(N, 2)];
for (int j = 0; j < N; j++)
for (int i = 0; i < N; i++)
{
RowMatrix[count1] = PatternBipolar[i, j];
count1++;
}
//convert to column matrix
int count2 = 0;
int[] ColMatrix = new int[(int)Math.Pow(N, 2)];
for (int j = 0; j < N; j++)
for (int i = 0; i < N; i++)
{
ColMatrix[count2] = PatternBipolar[i, j];
count2++;
}
//multiplication
int[,] MultipliedMatrix = new int[(int)Math.Pow(N, 2), (int)Math.Pow(N, 2)];
for (int i = 0; i < (int)Math.Pow(N, 2); i++)
for (int j = 0; j < (int)Math.Pow(N, 2); j++)
{
MultipliedMatrix[i, j] = ColMatrix[i] * RowMatrix[j];
}
//cells in the northwest diagonal get set to zero
for (int i = 0; i < (int)Math.Pow(N, 2); i++)
MultipliedMatrix[i, i] = 0;
// WightMatrix + MultipliedMatrix
for (int i = 0; i < (int)Math.Pow(N, 2); i++)
for (int j = 0; j < (int)Math.Pow(N, 2); j++)
{
WeightMatrix[i, j] += MultipliedMatrix[i, j];
}
And there is Present() function (this function is used to return answer for a given pattern):
public void Present(bool[,] Pattern)
{
int[] output = new int[(int)(int)Math.Pow(N, 2)];
for (int j = 0; j < N; j++)
for (int i = 0; i < N; i++)
{
OutputShowMatrix[i, j] = 0;
}
//convert bool to binary
int[] PatternBinary = new int[(int)Math.Pow(N, 2)];
int count = 0;
for (int j = 0; j < N; j++)
for (int i = 0; i < N; i++)
{
if (Pattern[i, j] == true)
{
PatternBinary[count] = 1;
}
else
{
PatternBinary[count] = 0;
}
count++;
}
count = 0;
int activation = 0;
for (int j = 0; j < (int)Math.Pow(N, 2); j++)
{
for (int i = 0; i < (int)Math.Pow(N, 2); i++)
{
activation = activation + (PatternBinary[i] * WeightMatrix[i, j]);
}
if (activation > 0)
{
output[count] = 1;
}
else
{
output[count] = 0;
}
count++;
activation = 0;
}
count = 0;
for (int j = 0; j < N; j++)
for (int i = 0; i < N; i++)
{
OutputShowMatrix[i, j] = output[count++];
}
In below images I trained Hopfield for characters A and P and when input patterns are like A or P, network recognize them in true way
Then I train it for character C:
This is where every things go wrong!
Now if I enter pattern like C, this issue happen:
And if enter pattern like A, see what happen:
And if train more patterns, whole of grid become black!
I've spotted only one mistake in your code: you perform only one iteration of node value calculation, without verifying if the values have converged. I've fixed this method like this:
public bool[,] Present(bool[,] pattern)
{
bool[,] result = new bool[N, N];
int[] activation = new int[N * N];
int count = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
activation[count++] = pattern[i, j] ? 1 : 0;
}
bool convergence = false;
while (!convergence)
{
convergence = true;
var previousActivation = (int[])activation.Clone();
for (int i = 0; i < N * N; i++)
{
activation[i] = 0;
for (int j = 0; j < N * N; j++)
{
activation[i] += (previousActivation[j] * WeightMatrix[i, j]);
}
activation[i] = activation[i] > 0 ? 1 : 0;
if (activation[i] != previousActivation[i])
{
convergence = false;
}
}
}
count = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
result[i, j] = activation[count++] == 1;
}
return result;
}
This slightly improves the results, however probably should also be improved to calculate the values asynchronously to avoid cycles.
Unfortunately, this still introduces the behaviour you've described. This is results from the phenomena called spurious patterns. For the network to learn more than one pattern consider training it with a Hebb rule. You can read about the spurious patterns, stability and learning of the Hopfield network here and here.

Index was out of range

I am getting this error...
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index.
in the code at the indicated position.
List<int>[] tetangga = new List<int>[this.observasi];
for (int i = 0; i < this.observasi; i++)
{
tetangga[i] = new List<int>();
for (int j = 0; j < this.observasi; j++)
{
if (tableWeight[i, j] > 0)
{
tetangga[i].Add(j);
}
}
}
this.dataTable.ColumnCount = 2;
this.dataTable.Columns[0].HeaderCell.Value = "REGION";
this.dataTable.Columns[1].HeaderCell.Value = "REGION NEIGHBOR";
this.dataTable.Columns[1].SortMode = DataGridViewColumnSortMode.NotSortable;
this.dataTable.Columns[0].SortMode = DataGridViewColumnSortMode.NotSortable;
this.dataTable.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
int jlhRow = 0;
for (int i = 0; i < this.observasi; i++)
{
jlhRow = jlhRow + tetangga[i].Count;
}
this.dataTable.RowCount = jlhRow;
int row = 0;
for (int k = 0; k < this.observasi; k++)
{
this.dataTable[0, row].Value = this.nameRegion[k]; // <-- error occurs here
for (int l = 0; l < tetangga[k].Count; l++)
{
this.dataTable[1, row].Value = this.nameRegion[tetangga[k][l]];
row++;
}
}
Can anyone explain to me why?
You problem is here
for (int j = 0; j < this.observasi; j++)
{
if (tableWeight[i, j] > 0)
{
tetangga[i].Add(j);
}
}
How do we know what the 2nd dimension of tableWeight is? I expect it does not go up to this.observasi.
Put a break point at the start of your loop, before the line:
this.dataTable[0, row].Value = this.nameRegion[k];
Examine dataTable and nameRegion in the debugger and you may answer your own question. It's likely that the collections do not contain elements at the indexes you are specifying.

Categories

Resources