How to fill a three dimensional array - c#

I want to fill a three dimensional array with the following arrays:
double[] y11 = new double[7] { 24, 13.3, 12.2, 14, 22.2, 16.1, 27.9 };
double[] y12 = new double[7] { 3.5, 3.5, 4, 4, 3.6, 4.3, 5.2 };
double[] y21 = new double[7] { 7.4, 13.2, 8.5, 10.1, 9.3, 8.5, 4.3 };
double[] y22 = new double[7] { 3.5, 3, 3, 3, 2, 2.5, 1.5 };
double[] y31 = new double[5] { 16.4, 24, 53, 32.7, 42.8 };
double[] y32 = new double[5] { 3.2, 2.5, 1.5, 2.6, 2 };
double[] y41 = new double[2] { 25.1, 5.9 };
double[] y42 = new double[2] { 2.7, 2.3 };
for instance y12 means the array in group 1 , column number 2 and so on. so i have 4 groups ,each group has 2 columns.
public class Matrix
{
double[, ,] matrix;
public void Initial(int groupSize, int columnSize, int valueSize)
{
matrix = new double[groupSize, columnSize, valueSize];
}
}
I need a simple flexible Add method for the matrix, rather than assigning each value like matrix[1][2][3] = value;
I've tried this, but couldn't get it work
public void Add(double[] columnArray, int groupIndex, int columnIndex)
{
matrix[i, y] = columnArray;
}

According to #Henk Holterman 's Comment (thank you), I've managed to solve the problem
public class Matrix
{
double[,][] matrix;
public Matrix(int groupSize, int columnSize)
{
matrix = new double[groupSize, columnSize][];
}
public void Add(double[] arr, int groupIndex, int columnIndex)
{
matrix[groupIndex, columnIndex] = arr;
}
public void Print()
{
int columnIndex = 0;
int groupIndex = 0;
int groupSize = matrix.GetLength(0);
int columnSize = matrix.GetLength(1);
while (groupIndex < groupSize)
{
for (int k = 0; k < matrix[groupIndex, columnIndex].Length; k++)
{
Console.Write(groupIndex + 1);
while (columnIndex < columnSize)
{
Console.Write(" {0}", matrix[groupIndex, columnIndex][k]);
columnIndex++;
}
Console.WriteLine();
columnIndex = 0;
}
groupIndex++;
}
}
}
Main Class
static Matrix m;
static void SetDataSet()
{
double[] y11 = new double[7] { 24, 13.3, 12.2, 14, 22.2, 16.1, 27.9 };
double[] y12 = new double[7] { 3.5, 3.5, 4, 4, 3.6, 4.3, 5.2 };
double[] y21 = new double[7] { 7.4, 13.2, 8.5, 10.1, 9.3, 8.5, 4.3 };
double[] y22 = new double[7] { 3.5, 3, 3, 3, 2, 2.5, 1.5 };
double[] y31 = new double[5] { 16.4, 24, 53, 32.7, 42.8 };
double[] y32 = new double[5] { 3.2, 2.5, 1.5, 2.6, 2 };
double[] y41 = new double[2] { 25.1, 5.9 };
double[] y42 = new double[2] { 2.7, 2.3 };
m.Add(y11, 0, 0);
m.Add(y12, 0, 1);
m.Add(y21, 1, 0);
m.Add(y22, 1, 1);
m.Add(y31, 2, 0);
m.Add(y32, 2, 1);
m.Add(y41, 3, 0);
m.Add(y42, 3, 1);
}
static void Main(string[] args)
{
m = new Matrix(4,2);
SetDataSet();
m.Print();
Console.ReadLine();
}
}

Related

optimization of an equation parameters using genetic sharp genetic algorithm

i have some data for example:
x=1, 2, 3, 4, 5
y=5, 4, 3, 2, 1
z=1, 2, 1, 1, 3
t=9, 12, 9, 9, 15.
i know that t=ax+by+c*z. here i know a=1,b=1 and c=3 and i need to find them by genetic algorithm by Genetic Sharp. i wrote the below code but i get the boundary values all times of -100,-100,-100.
can you help me on it?
NOTE that i need the GA to search on a large boundary for example here i selected -100 to 100 for each of a,b and c. in real case i need to bound it to -100000 to 10000 for example. also i need the at least 10 fraction digits also.
double[] x = new double[] { 1, 2, 3, 4, 5 };
double[] y = new double[] { 5, 4, 3, 2, 1 };
double[] z = new double[] { 1, 2, 1, 1, 3 };
double[] t = new double[] { 9, 12, 9, 9, 15 };
var selection = new EliteSelection();
var crossover = new UniformCrossover();
var mutation = new FlipBitMutation();
var fitness = new FuncFitness((c) =>
{
var vals = (c as FloatingPointChromosome).ToFloatingPoints();
double err = 0;
for (int i = 0; i < x.Count(); i++)
{
err += Math.Pow((t[i] - (vals[0] * x[i] + vals[1] * y[i] + vals[2] * z[i])), 2);
}
return err;
});
var chromosome = new FloatingPointChromosome(
new double[] { -100, -100, -100 },
new double[] { 100, 100, 100 },
new int[] { 64, 64, 64 },
new int[] { 10, 10, 10 });
var population = new Population(100, 100, chromosome);
var ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation);
ga.Termination = new GenerationNumberTermination(300);
Console.WriteLine("GA running...");
ga.Start();
I think that is because the algorith wants to maximize the Fitness Function and in the way that you wrote it, the algo will find the worst possible values for your variables.
I changed the error calculation in the Fitness Function to
err -= Math.Pow((t[i] - (vals[0] * x[i] + vals[1] * y[i] + vals[2] * z[i])), 2);
so now the maximum possible value for err is zero and the algorith will try to find the variable values for it.
Got very close results running this code, although couldn't get the exact ones.
In this problem, by changing the fitness function and mutation the correct answer could be achieved using GeneticSharp. the modified code is as follows:
// x = 1, 2, 3, 4, 5
// y = 5, 4, 3, 2, 1
// z = 1, 2, 1, 1, 3
// t = 9, 12, 9, 9, 15.
// t = a*x + b*y + c*z
// a,b,c =???
double[] x = new double[] { 1, 2, 3, 4, 5 };
double[] y = new double[] { 5, 4, 3, 2, 1 };
double[] z = new double[] { 1, 2, 1, 1, 3 };
double[] t = new double[] { 9, 12, 9, 9, 15 };
var chromosome = new FloatingPointChromosome(
new double[] { -10, -10, -10 },
new double[] { 10.0, 10.0, 10.0 },
new int[] { 64, 64, 64 },
new int[] { 0, 0, 0 });
var fitness = new FuncFitness((c) =>
{
var fc = c as FloatingPointChromosome;
double err = 0;
var values = fc.ToFloatingPoints();
var pa = values[0];
var pb = values[1];
var pc = values[2];
var fitness_e = 0.0;
for (int i = 0; i < x.Count(); i++)
{
try
{
var expected_result = t[i];
var equations = (pa * x[i] + pb * y[i] + pc * z[i]);
var diff = Math.Abs(equations - expected_result);
fitness_e += diff;
}
catch (Exception)
{
return double.MinValue;
}
}
return fitness_e * -1;
});
var population = new Population(100, 500, chromosome);
var selection = new EliteSelection();
var crossover = new ThreeParentCrossover();
var mutation = new UniformMutation(true);
var ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation);
ga.Termination = new OrTermination(
new GenerationNumberTermination(5000),
new FitnessStagnationTermination(2000));
ga.CrossoverProbability = 0.1f;
ga.MutationProbability = 0.4f;
ga.Reinsertion = new ElitistReinsertion();
Console.WriteLine("GA running...");
var latestFitness = 0.0;
ga.GenerationRan += (sender1, e1) =>
{
var bestChromosome = ga.BestChromosome as FloatingPointChromosome;
var bestFitness = bestChromosome.Fitness.Value;
if (bestFitness != latestFitness)
{
latestFitness = bestFitness;
var phenotype = bestChromosome.ToFloatingPoints();
Console.WriteLine(
"Generation {0}: {1},{2},{3} fitness: {4}",
ga.GenerationsNumber,
phenotype[0],
phenotype[1],
phenotype[2],
bestFitness
);
}
};
ga.Start();
Console.WriteLine("GA End");

Splitting a 2D array into 4 smaller 2D arrays

I need to loop through a 2D array of ints that is 4x4, but I also have to create 4 2x2 arrays out of it. Then I have to loop through each of those 4 2x2 arrays to pick out the average of the numbers in each 2x2 array.
public int[,] Reduced(Sampler sampler)
{
int[,] a = new int[SampleSize,SampleSize];
for (int r = 0; r < Math.Sqrt(image.Length); r+=SampleSize)
{
for (int c = 0; c < Math.Sqrt(image.Length); c+=SampleSize)
{
InsideLoop(a, r, c);
}
}
return a;
}
private void InsideLoop(int[,] a, int r, int c)
{
for (r = 0; r < SampleSize; r++)
{
for (c = 0; c < SampleSize; c++)
{
a[r, c] = image[r, c];
Console.WriteLine("Value: {0}", a[r, c]);
}
}
}
This is essentially what I've got so far, but it's working how it's written instead of how I'd like it to work. For this example, SampleSize is a variable that is set to 2. What this does currently is print out the numbers that create the first 2x2 array four times. My laptop battery is about to die, so I can't elborate more, but if anyone has any tips while I'm driving home. I had to finish posting this on my phone.
Does this work?
int sampleSize = 2;
int[,] data = {
{1, 2, 3, 4 },
{5, 6, 7, 8 },
{9, 10, 11, 12 },
{13, 14, 15, 16 }
};
//assume input data is a perfect square as per your example
int max = (int)Math.Sqrt(data.Length);
List<int[,]> samples = new List<int[,]>();
int startX = 0;
while (startX + sampleSize <= max)
{
int startY = 0;
while (startY + sampleSize <= max)
{
int[,] sample = new int[sampleSize, sampleSize];
for (int x = 0; x < sampleSize;x++)
{
for (int y = 0; y < sampleSize; y++)
{
sample[x, y] = data[x + startX, y + startY];
}
}
samples.Add(sample);
startY += sampleSize;
}
startX += sampleSize;
}
//for output testing
foreach (int[,] sample in samples)
{
Console.WriteLine(sample[0, 0].ToString().PadLeft(2) + " | " + sample[0, 1]);
Console.WriteLine(" ----- ");
Console.WriteLine(sample[1, 0].ToString().PadLeft(2) + " | " + sample[1, 1]);
Console.WriteLine();
Console.WriteLine();
}
Console.ReadLine();
and here's the output
1 | 2
-----
5 | 6
3 | 4
-----
7 | 8
9 | 10
-----
13 | 14
11 | 12
-----
15 | 16
Generalized version:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
int[,] original = new int[,] { { 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };
int[,] harder = new int[,] { { 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, 65, 66, 67, 68, 69, 70, 71, 72 },
{ 73, 74, 75, 76, 77, 78, 79, 80, 81 } };
IterateArray(original);
Console.ReadLine();
}
static void IterateArray(int[,] array)
{
double tDim = Math.Sqrt(Math.Sqrt(array.Length));
int dim = (int)tDim;
if (dim != tDim) throw new ArgumentException("Not a valid array!");
for (int i = 0; i < dim; i++)
{
IterateRows(array, dim, i);
}
}
static void IterateRows(int[,] array, int dim, int pass)
{
int maxRow = dim * dim;
IList<int> list = new List<int>(maxRow);
for (int curRow = 0; curRow < maxRow; curRow++)
{
IterateColumns(array, dim, curRow, pass, list);
if (list.Count == maxRow)
{
PrintNewArray(list, dim);
list.Clear();
}
}
}
static void IterateColumns(int[,] array, int dim, int row, int pass, IList<int> list)
{
int maxCol = dim + (dim * pass);
for (int curCol = pass * dim; curCol < maxCol; curCol++)
{
list.Add(array[row, curCol]);
}
}
static void PrintNewArray(IList<int> list, int dim)
{
for(int i = 0; i < list.Count; i++)
{
if (i % dim == 0)
{
Console.WriteLine();
}
Console.Write($"{list[i]} ");
}
Console.WriteLine($"\nAverage {list.Average()}");
}
}

How to implement a multidimensional array shuffling in CSharp?

I wonder if it is possible to implement a general Julia\Matlab alike View function in C# that would work for arrays of any dimensions (eg [,,] and [,,,]) as they do it in array slicer\mover view. So I wonder if there is a library that provides similar functionality for CSharp multidimentional arrays or how to implement it in C#?
The solution is twofold:
Use a wrapper class that holds a reference to the master array
Use the Array base class to make it polymorphic
Wrapper
class View<T>
{
private readonly Array array;
private readonly int dim;
private readonly int slice;
public View(Array array, int dim, int slice)
{
this.array = array;
this.dim = dim;
this.slice = slice;
}
public T this[params int[] indexes]
{
get { return (T)array.GetValue(BaseIndexesFor(indexes)); }
set { array.SetValue(value, BaseIndexesFor(indexes)); }
}
private int[] BaseIndexesFor(int[] indexes)
{
if (indexes.Length != array.Rank - 1) throw new ArgumentException("indexes");
int i_index = 0;
int[] baseIndexes = new int[array.Rank];
for (int i = 0; i < baseIndexes.Length; i++)
{
baseIndexes[i] = (i == dim) ? slice : indexes[i_index++];
}
return baseIndexes;
}
}
2D example
var A = new int[,]
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
/* View(Array array, int dim, int slice)
*
* For 2 dimensional array:
* dim=0 -> rows
* dim=1 -> columns
*/
// From second dimension slice index 1
// Or simply, take column with index 1
var B = new View<int>(A, 1, 1);
B[2] = 0;
Console.WriteLine(A[2, 1]); // 0
3D examples
var C = new int[,,]
{
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
},
{
{ 11, 12, 13 },
{ 14, 15, 16 },
{ 17, 18, 19 }
},
{
{ 21, 22, 23 },
{ 24, 25, 26 },
{ 27, 28, 29 }
}
};
/* From first dimension slice index 2
* { 21, 22, 23 },
* { 24, 25, 26 },
* { 27, 28, 29 }
*/
var D = new View<int>(C, 0, 2);
D[1, 1] = 0;
Console.WriteLine(C[2, 1, 1]); // 0
/* From third dimension slice index 0
* { 1, 4, 7 },
* { 11, 14, 17 },
* { 21, 24, 27 }
*/
var E = new View<int>(C, 2, 0);
E[2, 0] = 0;
Console.WriteLine(C[2, 0, 0]); // 0

Randomly pick from a list of numbers until specific limit

Let's say I have a list of predefined numbers, and a list of predefined max limits.
When a user picks a limit, I need to randomly pick a certain amount of numbers from the first list, up until their totals match (As close to, but never over) the user selected total.
What I've tried so far:
void Main()
{
List<int> num = new List<int>(){ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19, 20 };
int maxNum = 17;
List<int> curNum = new List<int>();
int curTotal = 0;
foreach(int sel in num.Where(x => x < maxNum)){
curTotal += sel;
if(curTotal <= maxNum){
curNum.Add(sel);
}
}
}
There needs to be x amount of numbers picked. In this case, 5 numbers picked, +- 20 numbers to be randomly picked from, and 1 max values.
So the end list should look like this:
1, 2, 3, 4, 7 (17)
1, 2, 3, 5, 6 (17)
1, 2, 3, 4, 6 (16) <- This will be fine if there isn't a solution to the max value.
Building upon #AlexiLevenkov's answer:
class Program
{
static void Main(string[] args)
{
int limit = 17;
int listSize = 5;
List<int> a = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
a.Shuffle();
List<int> genList = new List<int>();
int stoppedCount = 0;
for (int i = 0; i < a.Count(); i++)
{
if (i < listSize)
{
genList.Add(a[i]);
stoppedCount = i;
}
else
{
break;
}
}
while (genList.Sum() > limit)
{
genList.Remove(genList.Max());
stoppedCount++;
genList.Add(a[stoppedCount]);
}
}
}
static class ThisClass
{
public static void Shuffle<T>(this IList<T> list)
{
Random rng = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
I think shuffle + "take while sum < limit" may be what you are looking for.
Something like following:
var shuffledList = num.ToList();
shuffledList.Shuffle();
var sum = 0;
var count = 0;
while (shuffledList[count] + sum < max)
{
sum += shuffledList[count++];
}
return shuffledList.Take(count);

Take slice from 2D array (int[ , ]) using LINQ in C#

I am not C# expert, and total LINQ beginner, having searched a bit in SO and Google without discovering how to do the following:
If I have, say, int[10,10] array, how can I get a 2D slice from it?
For example, if the values in the said array were dependent on their position (a[2,3] = 23, a[4,8] = 48, etc.), I'd like to perform the following pseudocode:
int[3,3] a_slice = slicer_method(a, 3, 6, 2, 5) // or anything equivalent to this
> [[ 32, 33, 34],
[ 42, 43, 44],
[ 52, 53, 54]]
It doesn't have specifically to use LINQ, but I've seen LINQ used in every similar operation I've come across lately.
#JaredPar is correct, there is no intrinsic way to do slices - that said, you can craft up an extension method to do so:
public static class Ext
{
public static T[] Slice<T>(this T[] source, int fromIdx, int toIdx)
{
T[] ret = new T[toIdx - fromIdx + 1];
for(int srcIdx=fromIdx, dstIdx = 0; srcIdx <= toIdx; srcIdx++)
{
ret[dstIdx++] = source[srcIdx];
}
return ret;
}
public static T[,] Slice<T>(this T[,] source, int fromIdxRank0, int toIdxRank0, int fromIdxRank1, int toIdxRank1)
{
T[,] ret = new T[toIdxRank0 - fromIdxRank0 + 1, toIdxRank1 - fromIdxRank1 + 1];
for(int srcIdxRank0=fromIdxRank0, dstIdxRank0 = 0; srcIdxRank0 <= toIdxRank0; srcIdxRank0++, dstIdxRank0++)
{
for(int srcIdxRank1=fromIdxRank1, dstIdxRank1 = 0; srcIdxRank1 <= toIdxRank1; srcIdxRank1++, dstIdxRank1++)
{
ret[dstIdxRank0, dstIdxRank1] = source[srcIdxRank0, srcIdxRank1];
}
}
return ret;
}
}
And a test:
void Main()
{
var singleArr = new int[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
singleArr.Slice(2, 4).Dump();
var doubleArr = new int[,]
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
};
doubleArr.Slice(2, 4, 2, 4).Dump();
}
There is no way to do this on the CLR because it doesn't support the notion of array slices. They best you can do is create a wrapper type over arrays that simulates slices
You can try something like this:
public T[,] Slice<T>(T[,] a, int x1, int y1, int x2, int y2)
{
var result = new T[x2 - x1, y2 - y1];
for (var i = x1; i < x2; i++)
{
for (var j = y1; j < y2; j++)
{
result[i - x1, j - y1] = a[i,j];
}
}
return result;
}
sample
public class MyArraySlice<T> where T:struct {
public MyArraySlice(T[,] array, int xMin, int xMax, int yMin, int yMax) {
Array = array;
XMin = xMin; XMax = xMax;
YMin = yMin; YMax = yMax;
}
public T this[int i, int j] { get {
if (XMin <= i && i < XMax && YMin <= j && j < YMax)
return Array[i+XMin, j+YMin];
throw new ArgumentOutOfRangeException();
}
}
T[,] Array;
int XMin;
int XMax;
int YMin;
int YMax;
}

Categories

Resources