I am new in C# and I have a problem with for loops in lists.
I have a list with numbers (called alpha) which go from 0 to 7.
alpha0=1
alpha1=2
alpha2=3
...
alpha7=8
Now I want to create a matrix containing all these alphas in this way and then I want to transpose it:
I've tried to write the transposed one directly but it gives me error or better I am wrong with the syntax (see last string of my code). Could somebody help me?
I called startinglist my list with alphas.
List<List<double>> arr = new List<List<double>>();
for (int col = 0; col < 8; col++)
for (int row = 0; row < 7; row++)
arr[col, row].Add(startinglist[col]);
Try below code:
var size = 8;
var alpha = Enumerable.Range(1, size).ToArray();
var matrix = new int[size, size + 1];
for (int i = 0; i < size; i++)
{
// Assign values on the diagonal.
matrix[i, i] = alpha[i];
matrix[i, i + 1] = 1 - alpha[i];
}
Try this:
var size = 8;
int[] alpha = Enumerable.Range(1, size).ToArray();
int[][] C = new int[size - 1][];
for(int i = 0 ; i < size - 1; i++)
{
C[i] = new int[size];
C[i][i] = alpha[i];
C[i][i + 1] = 1 - alpha[i + 1];
}
Edit:
Since you have alpha already defined as a list, you may use this:
Edit2:
Changed int to double:
double[][] C = new double[alpha.Count - 1][];
for(int i = 0 ; i < alpha.Count - 1; i++)
{
C[i] = new double[alpha.Count];
C[i][i] = alpha[i];
C[i][i + 1] = 1 - alpha[i + 1];
}
Related
I have a 2d array[,] and I need to delete the border of it (or create a new array without it). I tried everything I thought of and nothing worked since I don't usually work with 2d arrays. Help please?
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7
becomes:
6 7
1 2
Queue<int> numbers = new Queue<int>();
int[,] b = new int[4, 4];
for (int i = 0; i < b.GetLength(0); i++)
{
for (int j = 0; j < b.GetLength(1); j++)
{
int x = int.Parse(Console.ReadLine());
b[i, j] = x;
}
}
int rows = b.GetLength(0);
Console.WriteLine("Number of rows: "+rows);
int columns = b.GetLength(1);
Console.WriteLine("Number of columns: " + columns);
int[,] arrayUpdated = new int[columns - 2,rows - 2];
for (int n = 0; n < b.GetUpperBound(1); n++)
{
for (int i = 0; i < b.GetUpperBound(0); i++)
{
arrayUpdated[i, n] = b[i, n];
Console.WriteLine(arrayUpdated[i, n]);
}
}
public static T[,] RemoveBorders<T>(T[,] source)
{
//index of last item, not number of items
var ROW = source.GetUpperBound(0);
if (ROW < 2) throw new ArgumentException("source array is not tall enough");
var COL = source.GetUpperBound(1);
if (COL < 2) throw new ArgumentException("source array is not wide enough");
var result = new T[ROW - 1, COL - 1];
for (int r = 1; r < ROW; r++)
{
for (int c = 1; c < COL; c++)
{
result[r-1, c-1] = source[r, c];
}
}
return result;
}
https://dotnetfiddle.net/dtUpRA
You would use it in the code in the question like this:
int[,] arrayUpdated = RemoveBorders(b);
Basically i'm trying to multiply each element of the first array with each element of the second array and then store it all at the end as a total. I'm pretty new to coding so just trying to learn and this one really has me stuck. This is the example of what it should eventually do.
ExampleArray1 = 5,6,7,8
ExampleArray2 = 2,3,4
(5*2)+(5*3)+(5*4) + (6*2)+(6*3)+(6*4) + (7*2)+(7*3)+(7*4) + (8*2)+(8*3)+(8*4) = 234
My code
int[] firstArray = { 5, 6, 7, 8 };
int[] secondArray = { 2, 3, 4 };
int[] thirdArray = new int[firstArray.Length * secondArray.Length];
for (int i = 0; i < firstArray.Length; i++)
for (int j = 0; j < secondArray.Length; j++)
{
thirdArray[i * firstArray.Length + j] = firstArray[i] * secondArray[j];
Console.WriteLine(thirdArray[i * firstArray.Length + j]);
}
You dont need a third array, you can just sum the results
var total = 0;
for (int i = 0; i < firstArray.Length; i++)
for (int j = 0; j < secondArray.Length; j++)
{
total += (firstArray[i] * secondArray[j]);
}
Console.WriteLine(total);
However you forgot to minus one form the length, in the third array index.
i.e to get the index you need i * (firstArray.Length - 1) + j
int[] thirdArray = new int[firstArray.Length * secondArray.Length];
for (int i = 0; i < firstArray.Length; i++)
for (int j = 0; j < secondArray.Length; j++)
{
thirdArray[i * (firstArray.Length - 1) + j] = firstArray[i] * secondArray[j];
}
Console.WriteLine(thirdArray.Sum());
You can apply some basic algebra to simplify this:
var total = 0;
var array1Total = 0;
var array2Total = 0;
for (int i = 0; i < firstArray.Length; i++)
{
array1Total += firstArray[i];
}
for (int j = 0; j < secondArray.Length; j++)
{
array2Total += secondArray[j];
}
total = array1Total * array2Total;
Console.WriteLine(total);
The reason is that if you expand (x0+x1+x2+x3...)*(y0+y1+y2+...) then you can see that you will multiply x0 by each of the y, then multiply x1 by each of the y, and so on. So you'll get each of the elements in the first brackets multiplied by each of the elements in the second brackets.
While this may not seem much different it will be considerably better for large arrays. if the length of your arrays are m and n then by the nested loops method you'll have m*n loop iterations. With the above technique you will have m+n. For small values this isn't a big deal. If you have arrays of thousands of items then the above will be significantly faster.
Of course, there is an even easier way to do the above:
var total = firstArray.Sum()*secondArray.Sum();
I've run into a stall trying to put together some code to average out 10x10 subarrays of a 2D multidimensional array.
Given a multidimensional array
var myArray = new byte[100, 100];
How should I go about creating 100 subarrays of 100 bytes (10x10) each.
Here are some examples of the value indexes the subarrays from the multidimensional would contain.
[x1,y1,x2,y2]
Subarray1[0,0][9,9]
Subarray2[10,10][19,19]
Subarray3[20,20][29,29]
Given these subarrays, I would then need to average the subarray values to create a byte[10,10] from the original byte[100,100].
I realize this is not unbelievably difficult, but after spending 4 days debugging very low-level code and now getting stuck on this would appreciate some fresh eyes.
Use this as a reference. I used ints just for ease of use. Code is untested. but the idea is there.
var rowSize = 100;
var colSize = 100;
var arr = new int[rowSize, colSize];
var r = new Random();
for (int i = 0; i < rowSize; i++)
for (int j = 0; j < colSize; j++)
arr[i, j] = r.Next(20);
for (var subcol = 0; subcol < colSize / 10; subcol++)
{
for (var subrow = 0; subrow < colSize/10; subrow++)
{
var startX = subcol*10;
var startY = subrow*10;
var avg = 0;
for (var x=0; x<10; x++)
for (var y = 0; y < 10; y++)
avg += arr[startX + x, startY + y];
avg /= 10*10;
Console.WriteLine(avg);
}
}
It looks like you're new to SO. Next time try to post your attempt at the problem; it's better to fix your code.
The only challenge is figuring out the function, that given the subarray index we're trying to populate, would give you the correct row and column indexes in your original 100x100 array; the rest would just be a matter of copying the values:
// psuedocode
// given a subarrayIndex of 0 to 99, these will calculate the correct indices
rowIndexIn100x100Array = (subarrayIndex / 10) * 10 + subArrayRowIndexToPopulate;
colIndexIn100x100Array = (subarrayIndex % 10) * 10 + subArrayColIndexToPopulate;
I'll leave it as an exercise to you to deduce why the above functions correctly calculate the indices.
With the above, we can easily map the values:
var subArrays = new List<byte[,]>();
for (int subarrayIndex = 0; subarrayIndex < 100; subarrayIndex++)
{
var subarray = new byte[10, 10];
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
{
int rowIndexIn100x100Array = (subarrayIndex / 10) * 10 + i;
int colIndexIn100x100Array = (subarrayIndex % 10) * 10 + j;
subarray[i, j] = originalArray[rowIndexIn100x100Array, colIndexIn100x100Array];
}
subArrays.Add(subarray);
}
Once we have the 10x10 arrays, calculating the average would be trivial using LINQ:
var averages = new byte[10, 10];
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
{
averages[i, j] = (byte)subArrays[(i * 10) + j].Cast<byte>().Average(b => b);
}
Fiddle.
Really I'm trying to apply 3X3 Median Filtering by C# and depending on my understanding the concepts of Median Filtering I wrote the following code but when I'm running it the Form hangs. I think have some problem in the last nested for loop but i don't know where is the error or the wrong in applying the Median concepts!
public static Bitmap MedianFiltering(Bitmap bm)
{
List<int> termsList = new List<int>();
Bitmap res, temp;
Color c;
int counter = 0;
//Convert to Grayscale
for (int i = 0; i < bm.Width; i++)
{
for (int j = 0; j < bm.Height; j++)
{
c = bm.GetPixel(i, j);
byte gray = (byte)(.333 * c.R + .333 * c.G + .333 * c.B);
bm.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
}
}
temp = bm;
//applying Median Filtering
for (int i = 0; i <= temp.Width - 3; i++)
for (int j = 0; j <= temp.Height - 3; j++)
{
for (int x = i; x <= i + 2; x++)
for (int y = j; y <= j + 2; y++)
{
c = temp.GetPixel(x, y);
termsList.Add(c.R);
counter++;
}
int[] terms = termsList.ToArray();
Array.Sort<int>(terms);
Array.Reverse(terms);
int color = terms[4];
temp.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
counter = 0;
}
res = temp;
return res;
}
Thanks.
You are not clearing the termsList after each pixel processing. This is causing the list to keep growing. Sorting and reversing the list will keep taking longer and longer times. This will also cause incorrect results since you only want to get the median of the 9 pixels related to the current pixel.
Simply clear the list like this:
...
int[] terms = termsList.ToArray();
termsList.Clear();
...
UPDATE:
I did more optimization for the code:
public static void MedianFiltering(Bitmap bm)
{
List<byte> termsList = new List<byte>();
byte[,] image = new byte[bm.Width,bm.Height];
//Convert to Grayscale
for (int i = 0; i < bm.Width; i++)
{
for (int j = 0; j < bm.Height; j++)
{
var c = bm.GetPixel(i, j);
byte gray = (byte)(.333 * c.R + .333 * c.G + .333 * c.B);
image[i, j] = gray;
}
}
//applying Median Filtering
for (int i = 0; i <= bm.Width - 3; i++)
for (int j = 0; j <= bm.Height - 3; j++)
{
for (int x = i; x <= i + 2; x++)
for (int y = j; y <= j + 2; y++)
{
termsList.Add(image[x, y]);
}
byte[] terms = termsList.ToArray();
termsList.Clear();
Array.Sort<byte>(terms);
Array.Reverse(terms);
byte color = terms[4];
bm.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
}
}
Please note that in your original method, you returned a Bitmap. I removed this.
Please note that temp = bm; does not create a copy of the Bitmap. It is just pointing the temp variable to the same object (that is pointed by bm). So in your original method, you returned the exact object that is passed in the method parameter. To use the new method pass the Bitmap and then the bitmap it self will be modified (this is also true for your method).
This enhanced performance 4 times on my machine.
What I did is mainly read the bitmap data into a byte array instead of using the Bitmap it self to read/write data multiple times.
If you need to further enhance the performance, take a look at this question.
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();