Remove row from multidimensional array in jagged array - c#

I have a jagged array with a multidimensional array and want to remove an array inside the multidimensional array. My code is:
int[][,] arr = new int[4][,];
arr[0] = new int[,] {
{ 1, 2, 3 }, // <- I want to remove this row
{ 4, 5, 6 },
{ 5, 6, 7 },
{ 8, 9, 10 } };
arr[1] = new int[,] {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };
arr[2] = new int[,] {
{ 1, 2, 3, 4, 5 },
{ 5, 6, 7, 8, 9 },
{ 10, 11, 12, 13, 14 },
{ 15, 16, 17, 18, 19 } };
arr[3] = new int[,] {
{ 1, 2, 3, 4, 5, 6},
{ 5, 6, 7, 8, 9, 10},
{ 11, 12, 13, 14, 15, 16 },
{ 17, 18, 19, 20, 21, 22 } };
int[,] removeArray = { { 1, 2, 3 } };
I tried to remove {1, 2, 3} from arr[0] by using Linq:
arr = arr
.Where((val, i) => i != 0)
.ToArray();
but this removes the whole arr[0] row. Does anyone know how I can get to remove {1,2,3} using Linq?

Unlike jagged arrays, multidimensional ones doesn't consist of arrays:
int[][] jagged = new int[][] {
new[] { 1, 2, 3 }, // <- this is an array
new[] { 4, 5 }, // <- this is another array
};
int[,] array2D = new int[,] {
{ 1, 2, 3 }, // <- not an array
{ 4, 5, 6 }, // <- not an array
};
So if you want to "remove" row from 2d array, you have to recreate it; something like this:
private static T[,] RemoveRows<T>(T[,] source, T[] row) {
if (row.Length != source.GetLength(1))
return source;
var keepRows = new List<int>();
for (int r = 0; r < source.GetLength(0); ++r)
for (int c = 0; c < row.Length; ++c)
if (!object.Equals(source[r, c], row[c])) {
keepRows.Add(r);
break;
}
if (keepRows.Count == source.Length)
return source;
T[,] result = new T[keepRows.Count, source.GetLength(1)];
for (int r = 0; r < keepRows.Count; ++r)
for (int c = 0; c < result.GetLength(1); ++c)
result[r, c] = source[keepRows[r], c];
return result;
}
and then
// we remove row; let it be 1d array, not 2d one
int[] removeArray = { 1, 2, 3 };
arr = arr
.Select(array => RemoveRows(array, removeArray))
.ToArray();
please, fiddle yourself

Related

How to remove all occurrences in array and shift leftovers left?

We have two arrays of integers a1 and a2 as parameters and we should remove all occurrences of a2 values from a1. Element is "removed" by shifting all subsequent elements one index to the left to cover it up, placing a 0 into the last index. The original relative ordering of a1 elements should be retained.
i'm having problem with shifting it's element.
Example:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1};
int[] a2 = { 42, 2222, 9};
the final result should be like this:
{3, 0, 17, 8, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
so here is my code:
for(int i = 0; i < a1.Length; i++)
{
foreach(var element in a2)
{
if (element == a1[i])
{
for(int j = i; j < a1.Length-1; j++)
{
a1[j] = a1[j+1];
}
a1[a1.Length - 1] = 0;
}
}
}
You need to use i--; when your item matches. Because you're shifting your entire array. Also you need to use break; your inner foreach loop after i--;.
Explanation
1) With your arrays, for i = 0 and first element in foreach(var element in a2) both will be 42. So first your array will be shifted one index. Now if you are not using i-- then it will check for i=1 which should be 3 but as we already shifted our array so 3 value is at index 0. So this value will never getting checked for match.
2) And use of break, as your match already found and array is shifted there is no requirement for check further.
Your code should be like below.
for(int i = 0; i < a1.Length; i++)
{
foreach(var element in a2)
{
if (element == a1[i])
{
for(int j = i; j < a1.Length-1; j++)
{
a1[j] = a1[j+1];
}
a1[a1.Length - 1] = 0;
i--;
break;
}
}
}
If You can use Linq then try as below, First get filters elements first. Then add 0 for rest indexes.
int[] a1= { 42,3,9,42,42,0,42,9,42,42,17,8,2222,4,9,0,1};
int[] a2= { 42,2222,9};
var a3 = a1.Where(x => !a2.Contains(x)).ToArray();
for (int i = 0; i < a1.Length; i++) {
if (i < a3.Length)
a1[i] = a3[i];
else
a1[i] = 0;
}
You can do this without creating any extra arrays like so:
static void Main()
{
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
int j = 0;
for (int i = 0; i < a1.Length; ++i)
if (Array.IndexOf(a2, a1[i]) < 0) // Don't remove this value.
a1[j++] = a1[i];
Array.Clear(a1, j, a1.Length-j);
Console.WriteLine(string.Join(", ", a1));
}
We make two passes: Firstly to remove all the elements of a1 that are contained in a2 (via the explicit loop) and then to overwrite all the "removed" values with 0 (via Array.Clear().
Just a different approach by first filtering and then adding the needed zeros:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
var zeros = Enumerable.Repeat(0, int.MaxValue);
var valids = a1.Where(v => !a2.Contains(v));
var result = valids.Concat(zeros).Take(a1.Length);
Console.WriteLine(String.Join(", ", result));
Yet another approach, using Array.Copyfor shifting:
public static void Main()
{
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
for(int i = 0; i < a1.Length; i++)
{
if(a2.Contains(a1[i]))
{
//notice i-- here because iterating array shifted to left
ShiftToLeft(a1, i--+1);
}
}
Console.WriteLine(string.Join(",", a1));
}
private static void ShiftToLeft(int[] array, int fromIndex)
{
Array.Copy(array, fromIndex, array, fromIndex-1, array.Length - fromIndex);
array[array.Length-1] = 0;
}
Try This:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
var result = a1.Where(x => !a2.Contains(x)).Concat(new int[a1.Length]).Take(a1.Length);
Console.WriteLine(String.Join(", ", result));

C# correct way to Iterate over 2d array as a subset 2d array

For an example if I want to iterate test and perfrorm operations on elements from that array but they have to be formatted in a particular way.
Essentially I am trying to loop over a 2d array using a 2d array.
double[,] test = {
{9, 8, 7, 6, 5, 4, 3, 2},
{8, 7, 6, 5, 4, 3, 2, 1},
{7, 6, 5, 4, 3, 2, 1, 0},
{6, 5, 4, 3, 2, 1, 0, 0},
{5, 4, 3, 2, 1, 0, 0, 0},
{4, 3, 2, 1, 0, 0, 0, 0},
{3, 2, 1, 0, 0, 0, 0, 0},
{2, 1, 0, 0, 0, 0, 0, 0},
};
double[,] subset = new double[2,2]; //used in math
What I would like to be able to do is to iterate over any size matrix (assuming that they are even sized and square) with each iteration looking like this:
Iteration 1:
subset[0,0] = test[0,0];
subset[0,1] = test[0,1];
subset[1,0] = test[1,0];
subset[1,1] = test[1,1];
So basically it selected a square same size as subset out of the large matrix.
Iteration 2:
subset[0,2] = test[0,2];
subset[1,2] = test[1,2];
subset[0,3] = test[0,3];
subset[1,3] = test[1,3];
You can do this via an extension method. A few things worth mentioning:
Using Array.Copy as opposed to manually assigning the elements should yield better performance.
Like Tom A mentioned in a comment, you should use yield return to create an IEnumerable. You can then iterate over it using a foreach loop, or perform other operations.
Implementation:
static class MatrixExtensions
{
public static IEnumerable<T[,]> ChunkMatrix<T>(this T[,] inputMatrix, int chunkWidth, int chunkHeight)
{
int inputWidth = inputMatrix.GetLength(0);
int inputHeight = inputMatrix.GetLength(1);
for(int i = 0; i < inputWidth; i += chunkWidth)
{
for(int j = 0; j < inputHeight; j += chunkHeight)
{
T[,] chunk = new T[chunkWidth, chunkHeight];
for(int k = 0; k < chunkWidth; k++)
{
int sourceIndex = i*inputWidth + k* inputWidth + j;
var destinationIndex = k* chunkHeight;
Array.Copy(inputMatrix, sourceIndex, chunk, destinationIndex, chunkHeight);
}
yield return chunk;
}
}
}
}
Usage:
double[,] test = {
{1, 2, 3, 4, 5, 6, 7, 8},
{9, 10, 11, 12, 13, 14, 15, 16},
{17, 18, 19, 20, 21, 22, 23, 24},
{25, 26, 27, 28, 29, 30, 31, 32},
{33, 34, 35, 36, 37, 38, 39, 40},
{41, 42, 43, 44, 45, 46, 47, 48},
{49, 50, 51, 52, 53, 54, 55, 56},
{57, 58, 59, 60, 61, 62, 63, 64},
};
foreach(double[,] chunk in test.ChunkMatrix(2, 2))
{
// First iteration:
// 1 2
// 9 10
//
// Second iteration:
// 3 4
// 11 12
//
// ...
}
I changed your test data to not include duplicate values, as to better illustrate the effect.
It should be noted that my implementation will not work correctly on matrices with dimensions that are not multiples of the chunks' dimensions, as it was mentioned in a comment that this will never be the case. If needed, modifying it to account for this scenario shouldn't be too hard.
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
const int COLUMNS = 8;
const int ROWS = 8;
const int SIZE = 2;
static void Main(string[] args)
{
double[,] test = {
{9, 8, 7, 6, 5, 4, 3, 2},
{8, 7, 6, 5, 4, 3, 2, 1},
{7, 6, 5, 4, 3, 2, 1, 0},
{6, 5, 4, 3, 2, 1, 0, 0},
{5, 4, 3, 2, 1, 0, 0, 0},
{4, 3, 2, 1, 0, 0, 0, 0},
{3, 2, 1, 0, 0, 0, 0, 0},
{2, 1, 0, 0, 0, 0, 0, 0},
};
for (int i = 0; i < COLUMNS; i += SIZE)
{
for (int j = 0; j < ROWS; j += SIZE)
{
for (int k = j; k < j + SIZE; k++)
{
for (int l = i; l < i + SIZE; l++)
{
Console.WriteLine("test[{0}, {1}] = {2}", k, l, test[k, l]);
}
}
}
}
Console.ReadLine();
}
}
}
I am not saying this is the best solution but while I look at the yield statement I managed to get it working using this method.
public static double[,] GetMapSection(Rectangle area, double[,] map) {
double[,] result = new double[area.Width, area.Height];
for (Int32 y = 0; y < area.Height; ++y) {
for (Int32 x = 0; x < area.Width; ++x) {
result[x, y] = map[x + area.X, y + area.Y];
}
}
return result;
}
I call it via:
List<double[,]> testChannel = new List<double[,]>();
for (int i = 0; i < Math.Sqrt(large_mapdata.Length); i+=8) {
for (int j = 0; j < Math.Sqrt(large_mapdata.Length); j+=8) {
testChannel.Add(GetMapSection(new Rectangle(i, j, 8, 8), large_mapdata));
}
}
In this example I am creating 8x8 chunks out of an array that is 32x32 in size.
I can confirm that this worked for me and is cleaner than what I had before.

How to find the total of each column in 2D-array

Note: the array and total of columns should be appear as below figure (numbers should not be
the same as figure below, numbers should be random)
5 1 1 1 1 1 1 1 1 1
2 2 4 5 6 7 8 8 9 9
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 5 5
4 4 4 4 4 4 4 4 4 4
7 7 7 7 7 7 7 7 7 7
3 3 3 3 3 3 3 3 3 3
1 1 1 1 1 1 1 11 1 1
The total of each column
33 29 31 32 33 34 35 45 36 36
`enter coddouble[,] a = new double[10, 10];
Random x = new Random();
string s = "";
for (int r = 0; r < 10; r++)
{
for (int c = 0; c < 10; c++)
{
a[r, c] = x.Next(1, 21);
s = s + a[r, c].ToString() + "\t";
}
}
textBox1.Text = s;e here`
this is how to print the arry now how to find the sum of each column
It is very basic in array implementation.
There are many ways to achieve this.One of my preferred way by iterating over the array structure using simple loop like this.
static int array[10][10];
//or like
int[,] array = new int[,]
{
<declare array structure>
};
int i, j, rowlength=10, columnlength=10, sum = 0; //assuming your order 10 as given example .To make it dynamic use array.Length
sum = 0;
for (j = 0; j < columnlength; ++j)
{
for (i = 0; i < rowlength; ++i)
{
sum = sum + array[i][j];
}
Console.WriteLine(String.Format("Summation of {0}th column is {1}", j,sum));
sum=0;
}
var arr2d = new int[5];
arr2d[0] = {1,2,3,4,5};
// etc...
var arr = new int[arr2d.length];
for(int i=0; i<arr2d.length; i++) {
var item = arr2d[i];
for(int j=0; j<item.length; j++) {
arr[i] += item[j];
}
}
you can try the below code. It generic code and can work on any number of column, you don't need to hardcode number of column. columnSum List contain the sum of individual column
var array2D = Get2DArray(); //some function to populate, you can have your own way to populate your 2D array
List<int> columnSum = new List<int>();
for (int j = 0; j < array2D.length ; ++j)
{
int sum = 0;
for (int i = 0; i < array2D[j].length; ++i)
{
sum = sum + array2D[i][j];
}
columnSum.Add(sum); // columnSum List contain the sum of individual column
}
Try this using your code.
What I did was sum the column you add the number to the array. This is assuming c is column and r is row.
double[,] a = new double[10, 10];
Random x = new Random();
string s = "";
var colsum = new List<int>();
for (int r = 0; r < 10; r++)
{
var col = 0;
for (int c = 0; c < 10; c++)
{
col += x.Next(1, 21);
a[r, c] = col;
s = s + a[r, c].ToString() + "\t";
}
colsum.Add(col);
}
foreach(var col in colsum){
Console.WriteLine(colsum.ToString());
}
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[,] data = new int[,] {
{5, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{2 ,2, 4, 5, 6, 7, 8, 8, 9, 9},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
{5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
{7, 7, 7, 7, 7, 7, 7, 7, 7, 7},
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
{1, 1, 1, 1, 1, 1, 1, 11, 1, 1}
};
int[] sum = new int[10];
for (int row = 0; row < 10; row++)
{
for (int col = 0; col < 10; col++)
{
if (row == 0)
{
sum[col] = data[row, col];
}
else
{
sum[col] += data[row, col];
}
}
}
List<List<int>> data2 = new List<List<int>>() {
new List<int>() {5, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
new List<int>() {2 ,2, 4, 5, 6, 7, 8, 8, 9, 9},
new List<int>() {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
new List<int>() {2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
new List<int>() {3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
new List<int>() {5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
new List<int>() {4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
new List<int>() {7, 7, 7, 7, 7, 7, 7, 7, 7, 7},
new List<int>() {3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
new List<int>() {1, 1, 1, 1, 1, 1, 1, 11, 1, 1}
};
//using linq
int[] sum2 = data2.Select(s => s.Select((t, i) => new { num = t, col = i })).SelectMany(u => u).GroupBy(v => v.col).ToList().Select(w => w.Select(x => x.num).Sum()).ToArray();
}
}
}
​
It's pretty simple - just 2 nested for loops like this
static double[] SumColumns(double[,] source)
{
int rowCount = source.GetLength(0);
int colCount = source.GetLength(1);
var colSums = new double[colCount];
for (int row = 0; row < rowCount; row++)
for (int col = 0; col < colCount; col++)
colSums[col] += source[row, col];
return colSums;
}
Sample usage with your code:
int rows = 10, cols = 10;
var a = new double[rows, cols];
var x = new Random();
var sb = new StringBuilder();
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
a[r, c] = x.Next(1, 21);
if (c > 0) sb.Append("\t");
sb.Append(a[r, c]);
}
sb.AppendLine();
}
var colsSums = SumColumns(a);
for (int c = 0; c < cols; c++)
{
if (c > 0) sb.Append("\t");
sb.Append(colsSums[c]);
}
var s = sb.ToString();
textBox1.Text = s;
I know this is an old post but you can have it by the following single line,
var result = Enumerable.Range(0, sample.GetLength(1)).Select(c => Enumerable.Range(0, sample.GetLength(0)).Select(r => sample[r, c]).Sum()).ToArray();
Test with sample data
var sample = new int[10, 10]
{
{ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 2, 2, 4, 5, 6, 7, 8, 8, 9, 9 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
{ 1, 1, 1, 1, 1, 1, 1, 11, 1, 1 }
};
var row = sample.GetLength(0);
var column = sample.GetLength(1);
var result = Enumerable.Range(0, column).Select(c => Enumerable.Range(0, row).Select(r => sample[r, c]).Sum()).ToArray();
Gets sum of each column in an array with; 33, 29, 31, 32, 33, 34, 35, 45, 36, 36

neural network doesn't work correctly

I'm using (ENCOG library) to create and train neural network. It must find real fault vector(it has 12 numbers - like vector = signature of fault) from modeling dictionary (it has 70 faults, identifying on 12 frequencies).
In NN i have input(12 neuron = len of one input fault vector), hidden (14 neuron = 2* output neurons) and output(7 neuron - to recognise by '0\1' 70 faults) layers.
This is it code (on C#) with NN:
public static double[][] XORInput =
{
new double[] { 1, 1, 1, 1,1,1,1,2,2,2,2,2 },
new double[] { 5, 5, 5, 5,5,5,5,6,6,7,7,7 },
new double[] { 6, 6,6,6,6,6,5,5,5,1,2,3 },
new double[] { 3, 3, 3, 3,3,3,3,3,2,2,1,1 } ,
new double[] { 1, 1, 2, 2,2,3,3,3,3,3,3,3 },
new double[] { 1, 4, 2, 7,2,5,6,7,8,8,8,8 },
new double[] { 2, 3, 3, 3,3,3,3,3,3,3,2,2 },
new double[] { 7,7, 7, 7,7,8,8,8,7,7,7,7 },
new double[] { 6, 7, 7, 8,8,8,8,8,8,7,7,6 },
new double[] { 3, 3, 3, 4 ,4,4,4,4,4,3,3,3 },
new double[] { 1, 1, 1, 1,1,2,2,2,2,2,2,2 },
new double[] { 5, 5, 5, 5,5,6,6,6,6,6,6,7 },
new double[] { 1,2,3,4,5,6,7,8,1,2,3,1 },
new double[] { 1, 1, 1, 1,1,1,1,1,1,2,4,1 },
new double[] { 1, 1, 1, 1,1,1,1,1,1,1,1,1 },
new double[] { 5, 5, 5,5,5,5,5,5,5,5,5,5 },
new double[] {7, 8, 8, 8,8,7,6,4,1,2,2,2 },
new double[] { 2, 3, 3, 3,3,4,4,4,4,3,3,3 },
new double[] { 8, 8,8, 8,8,5,6,7,8,8,8,8 },
new double[] { 5, 5, 5, 5,5,6,8,6,1,1,1,1 },
new double[] { 1, 1, 1, 1,1,1,1,4,4,6,3,5 },
new double[] { 2, 2, 2, 2,2,2,2,2,3,3,3,3 },
new double[] { 6, 6, 6, 6,7,7,7,7,7,8,8,8 },
new double[] { 1, 16, 2, 6,71,72,73,27,74,81,81,58 },
new double[] { 2, 36, 3, 67,87,7,17,27,37,2,1,1 },
new double[] { 3, 46, 4, 8,4,5,6,7,22,8,18,2 },
new double[] { 4, 56, 12, 9,1,2,4,12,4,44,1,8 },
new double[] { 5, 66, 5, 6,17,4,5,11,5,7,8,9 },
new double[] { 6, 86, 6, 6, 10,2,5,8,1,3,5,1 },
new double[] { 66, 16, 14, 11,1,1,1,2,1,4,1,6 },
new double[] { 67, 6,11 , 16,2,2,2,7,21,2,1,9 },
new double[] { 7, 6, 10, 62,12,3,4,54,1,1,3,3 },
new double[] { 8, 16,9, 6,17,7,1,2,7,5,1,4 },
new double[] { 9, 26,11, 6,73,6,2,3,4,5,5,2 },
new double[] { 61, 21, 85, 61,5,2,5,1,6,3,4,5 },
new double[] { 31, 1, 11, 1,1,1,1,2,2,2,2,2 },
new double[] { 15, 5, 15, 5,5,5,5,6,6,7,7,7 },
new double[] { 36, 6,16,6,6,6,5,5,5,1,2,3 },
new double[] { 53, 3, 13, 3,3,3,3,3,2,2,1,1 } ,
new double[] { 71, 1, 22, 2,2,3,3,3,3,3,3,3 },
new double[] { 81, 4, 21, 7,2,5,6,7,8,8,8,8 },
new double[] { 12, 3, 13, 3,3,3,3,3,3,3,2,2 },
new double[] { 97,7, 71, 7,7,8,8,8,7,7,7,7 },
new double[] { 5, 7, 17, 8,8,8,8,8,8,7,7,6 },
new double[] { 13, 3, 13, 4,4,4,4,4,4,3,3,3 },
new double[] { 11, 1, 11, 1,1,2,2,2,2,2,2,2 },
new double[] { 55, 5, 51, 5,5,6,6,6,6,6,6,7 },
new double[] { 16,2,19,4,5,6,7,8,1,2,3,1 },
new double[] { 17, 1, 11, 1,1,1,1,1,1,2,4,1 },
new double[] { 19, 1, 21, 1,1,1,1,1,1,1,1,1 },
new double[] { 25, 5, 25,5,5,5,5,5,5,5,5,5 },
new double[] {27, 8, 28, 8,8,7,6,4,1,2,2,2 },
new double[] { 22, 3, 23, 3,3,3,3,3,3,2,1,7 },
new double[] { 32, 3, 27, 3,3,4,4,4,4,3,3,3 },
new double[] { 18, 8,2, 8,8,5,6,7,8,8,8,8 },
new double[] { 31, 1, 4, 1,1,1,1,4,4,6,3,5 },
new double[] { 23, 2, 6, 2,2,2,2,2,3,3,3,3 },
new double[] { 36, 6, 16, 6,7,7,7,7,7,8,8,8 },
new double[] { 31, 16, 5, 6,71,72,73,27,74,81,81,58 },
new double[] { 12, 36, 14, 67,87,7,17,27,37,2,1,1 },
new double[] { 31, 46, 41, 8,4,5,6,7,22,8,18,2 },
new double[] { 14, 56, 1, 9,1,2,4,12,4,44,1,8 },
new double[] { 15, 66, 59, 6,17,4,5,11,5,7,8,9 },
new double[] { 16, 86, 16, 6, 10,2,5,8,1,3,5,1 },
new double[] { 16, 16, 10, 11,1,1,1,2,1,4,1,6 },
new double[] { 17, 6,114, 16,2,2,2,7,21,2,1,9 },
new double[] { 71, 6, 1, 62,12,3,4,54,1,1,3,3 },
new double[] { 18, 16,19, 6,17,7,1,2,7,5,1,4 },
new double[] { 19, 26,1, 6,73,6,2,3,4,5,5,2 },
new double[] { 6, 21, 5, 61,5,2,5,1,6,3,4,5 } //70
};
/// <summary>
/// Array of numbers, which equal to squares of two
/// </summary>
static int[] powOfTwo = {2, 4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536 };
private static void Main(string[] args)
{
double[][] XORIdeal = computeOutputVector(XORInput);
// normalizing input data
double[][] input = normalizeData(XORInput);
// create a neural network, without using a factory
var network = new BasicNetwork();
network.AddLayer(new BasicLayer(null, true, 12));
network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 14));
network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, 7));
network.Structure.FinalizeStructure();
network.Reset();
// create training data
IMLDataSet trainingSet = new BasicMLDataSet(input, XORIdeal);
//IMLDataSet trainingSet = new BasicMLDataSet(XORInput, XORIdeal);
// train the neural network
//IMLTrain train = new ResilientPropagation(network, trainingSet);
//var train = new Backpropagation ( network , trainingSet , 0.3 , 0.7 ) ;
var train = new Backpropagation(network, trainingSet, 0.2, 0.15); // speed and influence of backpropogation algorithm
int epoch = 1;
do
{
train.Iteration();
Console.WriteLine(#"Epoch #" + epoch + #" Error:" + train.Error);
epoch++;
} while (train.Error > 0.05 && epoch < 2000);
train.FinishTraining();
// test the neural network
Console.WriteLine(#"Neural Network Results:");
double[] data = new double[] { 1, 1, 1, 1,1,1,1,2,2,2,2,2 }; //{ 5.1, 5.4, 5.5, 5.5, 5.8, 5.6, 5.6, 6.5, 6.6, 7.1, 7.1, 7.1 }; // 0000001
double[] realSignature22 = new double[] { 6.21, 4.2, 6.6, 6.6, 6.6, 5.56, 6.5, 7, 7, 6.89, 6.8, 8 }; // 0010110
double[] realSignature34 = new double[] { 58, 24, 90, 55, 4.5, 1.82, 5.4, 1.1, 6.4, 3.1, 3.4, 5.3 }; // 0100010
IMLData example1 = new BasicMLData(normilizeRow(data));
IMLData output1 = network.Compute(example1);
Console.WriteLine("\nactual : 0 0 0 0 0 0 0 = #0 ");
findNumber(output1);
IMLData example = new BasicMLData(normilizeRow(realSignature34));
IMLData output = network.Compute(example);
Console.WriteLine("\nactual : 0 1 0 0 0 1 0 = #34 ");
findNumber(output);
IMLData example2 = new BasicMLData(normilizeRow(realSignature22));
IMLData output2 = network.Compute(example2);
Console.WriteLine("\nactual : 0 0 1 0 1 1 0 = #22 ");
findNumber(output2);
EncogFramework.Instance.Shutdown();
}
/// <summary>
/// Returns degree of two which cowers number of mistakes in the input vector
/// </summary>
/// <param name="XORInput"></param>
/// <returns></returns>
static int calcSizeOfOutputVector(double[][] XORInput)
{
int size = 0;
int len = XORInput.GetLength(0);
foreach (int number in powOfTwo)
{
size++;
if (len <= number) return size;
}
return -1;
}
static double[][] computeOutputVector(double[][] XORInput)
{
double[][] output;
int sizeOfOut = calcSizeOfOutputVector(XORInput);
int numOfFaults = XORInput.GetLength(0);
output = new double[numOfFaults][];
// convert decimal number into corresponding array from 0 and 1 (equal to decimal number)
for (int i = 0; i < numOfFaults; i++)
{
output[i] = new double[sizeOfOut];
convertDecToByteAndSaveInDoubleArray(output[i], i);
}
return output;
}
static double[] convertDecToByteAndSaveInDoubleArray(double[] outArray, int number ){
// convert number into binary representation
string binaryCode = Convert.ToString(number, 2);
int size = outArray.GetLength(0);
// Initially fill with zeros
for (int i = 0; i < size; i++) outArray[i] = 0;
//
for (int i = 0; i < binaryCode.Length; i++)
{
double d = Double.Parse(binaryCode.Substring(binaryCode.Length - i - 1, 1));
outArray[size - 1 - i] = d;
}
return outArray;
}
static void printOutputResults(IMLData output){
Console.WriteLine("\nFrom NN ");
for (int i = 0; i < output.Count; i++ )
Console.Write(" " + output[i] + " " );
}
static int[] findNumber(IMLData output)
{
int len = output.Count;
// Round to 0 and 1 numbers, which is received from NN
int[] outAr = new int[len];
for (int i = 0; i < output.Count; i++)
{
outAr[i] = (int)Math.Round(output[i]);
}
// Display output vectors
// Bug for number 1 and length 7 in the input vector looks like : 0[0] 0[1] 0[2] 0[3] 0[4] 0[5] 1[6] (in binary system) = 1 (in decimal system)
Console.WriteLine("\nFrom NN ");
for (int i = 0; i < len; i++)
Console.Write(" " + outAr[i] + " ");
// Convert binary vector into decimal
Console.WriteLine("\nFrom NN (converted number)" + convertBinArrayToDecNumber(outAr));
return outAr;
}
static int convertBinArrayToDecNumber(int[] binaryArray)
{
int n = 0;
int maxIndex = binaryArray.Length - 1;
for (int i = maxIndex; i >= 0; i--)
n += (int)Math.Pow(2, maxIndex - i) * binaryArray[i];
return n;
}
static double[][] normalizeData(double[][] data)
{
int numOfRows = data.Length;
int lenOfRow = data[0].GetLength(0);
double[][] result = new double[numOfRows][];
for (int i = 0; i < numOfRows; i++)
result[i] = normilizeRow(data[i]);
return result;
}
static double[] normilizeRow(double[] row)
{
int lenOfRow = row.GetLength(0);
double[] result = new double[lenOfRow];
for (int i = 0; i < lenOfRow; i++) result[i] = 0;
double N = 0;
foreach (double num in row) N += num * num;
if (N != 0) {
for (int j = 0; j < lenOfRow; j++)
{
result[j] = (row[j] / Math.Sqrt(N));
}
}
return result;
}
I try to edit params of training by backpropogation, but almost everytime i have high train.error level.
But the most problem in this code is results. Each run of code has different (and not correct!!!) results. For ex:
actual : 0 0 0 0 0 0 0 = #0
From NN
0 0 0 0 0 0 1
From NN (converted number)1
actual : 0 1 0 0 0 1 0 = #34
From NN
0 1 0 0 0 1 0
From NN (converted number)34
actual : 0 0 1 0 1 1 0 = #22
From NN
0 0 0 0 0 1 0
From NN (converted number)2
Or another:
Neural Network Results:
actual : 0 0 0 0 0 0 0 = #0
From NN
0 0 0 0 1 0 1
From NN (converted number)5
actual : 0 1 0 0 0 1 0 = #34
From NN
0 1 0 0 0 1 0
From NN (converted number)34
actual : 0 0 1 0 1 1 0 = #22
From NN
0 0 0 1 1 1 1
From NN (converted number)15
Can anyone tell me:
1) how can I train the network more efficiently
2) why rows like '{ 1, 1, 1, 1,1,1,1,2,2,2,2,2 }' (which are in train data) doesn't correctly recognized by NN ?
//-------------------------------------------------------------------
I Try to normilize data with Encog function. Code:
public static void readCSVFileToNN(){
int numOfCol = 12;
// Define the format of the data file.
// This area will change, depending on the columns and
// format of the file that you are trying to model.
IVersatileDataSource source = new CSVDataSource("c:\\test.txt", false,
CSVFormat.DecimalPoint);
var data = new VersatileMLDataSet(source);
for (int i = 0; i < numOfCol; i++ )
data.DefineSourceColumn("freq#" +i , i, ColumnType.Nominal);
// Define the column that we are trying to predict.
ColumnDefinition outputColumn = data.DefineSourceColumn("faultNumbers", 12,
ColumnType.Nominal);
// Analyze the data, determine the min/max/mean/sd of every column.
data.Analyze();
// Map the prediction column to the output of the model, and all
// other columns to the input.
data.DefineSingleOutputOthersInput(outputColumn);
// Create feedforward neural network as the model type. MLMethodFactory.TYPE_FEEDFORWARD.
// You could also other model types, such as:
// MLMethodFactory.SVM: Support Vector Machine (SVM)
// MLMethodFactory.TYPE_RBFNETWORK: RBF Neural Network
// MLMethodFactor.TYPE_NEAT: NEAT Neural Network
// MLMethodFactor.TYPE_PNN: Probabilistic Neural Network
var model = new EncogModel(data);
model.SelectMethod(data, MLMethodFactory.TypeFeedforward);
// Send any output to the console.
model.Report = new ConsoleStatusReportable();
// Now normalize the data. Encog will automatically determine the correct normalization
// type based on the model you chose in the last step.
data.Normalize();
// Hold back some data for a final validation.
// Shuffle the data into a random ordering.
// Use a seed of 1001 so that we always use the same holdback and will get more consistent results.
model.HoldBackValidation(0.3, true, 1001);
// Choose whatever is the default training type for this model.
model.SelectTrainingType(data);
// Use a 5-fold cross-validated train. Return the best method found.
var bestMethod = (IMLRegression)model.Crossvalidate(2, true);
// Display the training and validation errors.
Console.WriteLine(#"Training error: " + model.CalculateError(bestMethod, model.TrainingDataset));
Console.WriteLine(#"Validation error: " + model.CalculateError(bestMethod, model.ValidationDataset));
// Display our normalization parameters.
NormalizationHelper helper = data.NormHelper;
Console.WriteLine(helper.ToString());
// Display the final model.
Console.WriteLine(#"Final model: " + bestMethod);
source.Close();
// test work of model on the example:
IMLData input = helper.AllocateInputVector();
var line = new String[numOfCol];
var result = new StringBuilder();
// в качестве примера возьмем сигнатуру [5,5,..,5] под номером 15
for (int i = 0; i < numOfCol; i++)
line[i] = 5.ToString();
String correct = 15.ToString();
// нормализуем входной вектор
helper.NormalizeInputVector(line, ((BasicMLData) input).Data, false);
// производим поиск по НС
IMLData output = bestMethod.Compute(input);
// выводим результат
String faultChosen = helper.DenormalizeOutputVectorToString(output)[0];
result.Append(line);
result.Append(" -> predicted: ");
result.Append(faultChosen);
result.Append("(correct: ");
result.Append(correct);
result.Append(")");
Console.WriteLine(result.ToString());
}
But results are still bad. I do this function ~10 times and no one of results were not correct
Your problem is that each row normalization is independent from other rows. For example the first row will be division of each value at 27, second row will be division of each number at 394. Another source of problems can be You need to normalize not each row independently, but all rows should be normalized according to some rule. Then you should apply the same normalization rule for your input. I propose you to look at function normalize in Encog.

Compare 2 List<int> and find 5 int numbers in a row C#

I got 2 int List like below
List<int> list1 = new List<int> { 2, 6, 1, 8, 9, 4, 12, 24, 23, 3, 11, 15 };
List<int> list2 = new List<int> { 6, 9, 4, 12, 24, 23, 5, 16, 18, 2, 7, 14 };
list1 = { 2, 6, 1, 8, 9, 4, 12, 24, 23, 3, 11, 15 };
list2 = { 6, 9, 4, 12, 24, 23, 5, 16, 18, 2, 7, 14, };
When I compare this 2 lists i need to get result in new List like:
{ 9, 4, 12, 24, 23 }
Need fast working solution under 500 ms. Original list contains 35 int items and need to find 5 same like on example above.
I guess the best what you can do is go through the list and see whether you find a good starting index.
for (int i = 0; i <= list1.Count - length; i++)
{
for (int j = 0; j <= list2.Count - length; j++)
{
var match = true;
for (int k = 0; k < length; k++)
{
if (list1[k] != list2[k]) { match = false; break; }
}
if (match)
{
Console.WriteLine("Starting indices are {0} and {1}", i,j);
break;
}
}
}
Edit2: Introduced variable length sublists
Edit: Maybe you can accelerate this solution by prefiltering the indices as you create sums of the 5-element-chunks and intersect these sums. This will need O(n) for creating the sums and O(n) for intersecting them. However, then it is up to your data distribution whether you can find the true substrings in less than O(n^2) but you might be lucky.
Alternatively, you can save the concatenation of the strings separated by e.g. a semicolon and then intersect the strings. This will run deterministal in O(n) but will have a high memory footprint.
Here's a dumb solution that executes for me in less than 0.000 seconds on my machine, and 0.016 seconds on .dotnetfiddle.
public static void Main()
{
List<int> list1 = new List<int> { 2, 6, 1, 8, 9, 4, 12, 24, 23, 3, 11, 15 };
List<int> list2 = new List<int> { 6, 9, 4, 12, 24, 23, 5, 16, 18, 2, 7, 14 };
CommonSublist(5, list1, list2).Dump();
}
private static List<int> CommonSublist(int length, List<int> list1, List<int> list2) {
for (int i=0;i<list1.Count-length;i++) {
for (int j=0;j<list2.Count-length;j++) {
List<int> output = new List<int>();
for (int k=0;k<length;k++) {
if (list1[i+k]==list2[j+k]) {
output.Add(list1[i+k]);
}
else {
break;
}
}
if (output.Count == length) {
return output;
}
}
}
return null;
}

Categories