Hi I have an assignment in which I need to resolve a system of linear equations using Gausian elimination method.
This is my code so far:
private static double[][] equation = new double[][]
{
new double[] {0.0, 8.0, 2.0, -7.0},
new double[] {3.0, 5.0, 2.0, 8.0},
new double[] {6.0, 2.0, 8.0, 26.0}
};
private const int rowSize = 3;
private const int columnSize = 4;
private static int pivotRow;
private static int curentRowIndex;
public static void GetTriangularMatrix()
public static void GetTriangularMatrix()
{
PrintMatrix();
for (int k = 0; k <= columnSize - 2; k++)
{
curentRowIndex = k;
double pivot = GetPivot(k);
SwapCurentRowWithPivotRow(pivot);
FindTriangularMatrix();
}
}
public static double GetPivot(int curentPivot)
{
double pivot = equation[curentPivot][curentPivot];
pivotRow = curentPivot;
for (int i = curentPivot; i <= rowSize - 1; i++)
{
if (pivot < equation[i][curentPivot])
{
pivot = equation[i][curentPivot];
pivotRow = i;
}
}
Console.WriteLine("Pivot Row is " + (pivotRow + 1));
Console.WriteLine("Pivot is " + pivot);
return pivot;
}
private static void SwapCurentRowWithPivotRow(double pivot)
{
if(pivot != equation[curentRowIndex][curentRowIndex])
{
double temp;
for (int i = 0; i <= columnSize - 1; i++)
{
temp = equation[curentRowIndex][i];
equation[curentRowIndex][i] = equation[pivotRow][i];
equation[pivotRow][i] = temp;
}
}
PrintMatrix();
}
public static void FindTriangularMatrix()
{
double[][] trangularMatrix = new double[rowSize][];
for (int j = curentRowIndex + 1; j <= rowSize - 1; j++)
{
trangularMatrix[j][curentRowIndex] = equation[j][curentRowIndex] / equation[curentRowIndex][curentRowIndex];
}
}
At FindTriangularMatrix() method when I try to assign some value to the triangularMatrix I get back a null reference exception.
I believe this is more of a syntax problem , it may be something I am missing because I have never worked with two dimensional arrays before.
Can anyone tell me what I am doing wrong and how can I correct it?
Related
I am working on a project that compares the time bubble and selection sort take. I made two separate programs and combined them into one and now bubble sort is running much faster than selection sort. I checked to make sure that the code wasn't just giving me 0s because of some conversion error and was running as intended. I am using System.Diagnostics; to measure the time. I also checked that the machine was not the problem, I ran it on Replit and got similar results.
{
class Program
{
public static int s1 = 0;
public static int s2 = 0;
static decimal bubblesort(int[] arr1)
{
int n = arr1.Length;
var sw1 = Stopwatch.StartNew();
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arr1[j] > arr1[j + 1])
{
int tmp = arr1[j];
// swap tmp and arr[i] int tmp = arr[j];
arr1[j] = arr1[j + 1];
arr1[j + 1] = tmp;
s1++;
}
}
}
sw1.Stop();
// Console.WriteLine(sw1.ElapsedMilliseconds);
decimal a = Convert.ToDecimal(sw1.ElapsedMilliseconds);
return a;
}
static decimal selectionsort(int[] arr2)
{
int n = arr2.Length;
var sw1 = Stopwatch.StartNew();
// for (int e = 0; e < 1000; e++)
// {
for (int x = 0; x < arr2.Length - 1; x++)
{
int minPos = x;
for (int y = x + 1; y < arr2.Length; y++)
{
if (arr2[y] < arr2[minPos])
minPos = y;
}
if (x != minPos && minPos < arr2.Length)
{
int temp = arr2[minPos];
arr2[minPos] = arr2[x];
arr2[x] = temp;
s2++;
}
}
// }
sw1.Stop();
// Console.WriteLine(sw1.ElapsedMilliseconds);
decimal a = Convert.ToDecimal(sw1.ElapsedMilliseconds);
return a;
}
static void Main(string[] args)
{
Console.WriteLine("Enter the size of n");
int n = Convert.ToInt32(Console.ReadLine());
Random rnd = new System.Random();
decimal bs = 0M;
decimal ss = 0M;
int s = 0;
int[] arr1 = new int[n];
int tx = 1000; //tx is a variable that I can use to adjust sample size
decimal tm = Convert.ToDecimal(tx);
for (int i = 0; i < tx; i++)
{
for (int a = 0; a < n; a++)
{
arr1[a] = rnd.Next(0, 1000000);
}
ss += selectionsort(arr1);
bs += bubblesort(arr1);
}
bs = bs / tm;
ss = ss / tm;
Console.WriteLine("Bubble Sort took " + bs + " miliseconds");
Console.WriteLine("Selection Sort took " + ss + " miliseconds");
}
}
}
What is going on? What is causing bubble sort to be fast or what is slowing down Selection sort? How can I fix this?
I found that the problem was that the Selection Sort was looping 1000 times per method run in addition to the 1000 runs for sample size, causing the method to perform significantly worse than bubble sort. Thank you guys for help and thank you TheGeneral for showing me the benchmarking tools. Also, the array that was given as a parameter was a copy instead of a reference, as running through the loop manually showed me that the bubble sort was doing it's job and not sorting an already sorted array.
To solve your initial problem you just need to copy your arrays, you can do this easily with ToArray():
Creates an array from a IEnumerable.
ss += selectionsort(arr1.ToArray());
bs += bubblesort(arr1.ToArray());
However let's learn how to do a more reliable benchmark with BenchmarkDotNet:
BenchmarkDotNet Nuget
Official Documentation
Given
public class Sort
{
public static void BubbleSort(int[] arr1)
{
int n = arr1.Length;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arr1[j] > arr1[j + 1])
{
int tmp = arr1[j];
// swap tmp and arr[i] int tmp = arr[j];
arr1[j] = arr1[j + 1];
arr1[j + 1] = tmp;
}
}
}
}
public static void SelectionSort(int[] arr2)
{
int n = arr2.Length;
for (int x = 0; x < arr2.Length - 1; x++)
{
int minPos = x;
for (int y = x + 1; y < arr2.Length; y++)
{
if (arr2[y] < arr2[minPos])
minPos = y;
}
if (x != minPos && minPos < arr2.Length)
{
int temp = arr2[minPos];
arr2[minPos] = arr2[x];
arr2[x] = temp;
}
}
}
}
Benchmark code
[SimpleJob(RuntimeMoniker.Net50)]
[MemoryDiagnoser()]
public class SortBenchmark
{
private int[] data;
[Params(100, 1000)]
public int N;
[GlobalSetup]
public void Setup()
{
var r = new Random(42);
data = Enumerable
.Repeat(0, N)
.Select(i => r.Next(0, N))
.ToArray();
}
[Benchmark]
public void Bubble() => Sort.BubbleSort(data.ToArray());
[Benchmark]
public void Selection() => Sort.SelectionSort(data.ToArray());
}
Usage
static void Main(string[] args)
{
BenchmarkRunner.Run<SortBenchmark>();
}
Results
Method
N
Mean
Error
StdDev
Bubble
100
8.553 us
0.0753 us
0.0704 us
Selection
100
4.757 us
0.0247 us
0.0231 us
Bubble
1000
657.760 us
7.2581 us
6.7893 us
Selection
1000
300.395 us
2.3302 us
2.1796 us
Summary
What have we learnt? Your bubble sort code is slower ¯\_(ツ)_/¯
It looks like you're passing in the sorted array into Bubble Sort. Because arrays are passed by reference, the sort that you're doing on the array is editing the same contents of the array that will be eventually passed into bubble sort.
Make a second array and pass the second array into bubble sort.
Can I use sort() function instead of this code to sort this list
private static void sortL1Descending(ref List<List<Object>> L1)
{
for (int i = 0; i < L1.Count; i++)
{
for (int j = 0; j < L1.Count -1; j++)
{
if (Convert.ToInt32(L1[j][1]) < Convert.ToInt32(L1[j + 1][1]))
{
List<Object> temp = L1[j];
L1[j] = L1[j + 1];
L1[j + 1] = temp;
}
}
}
}
You could use Sort(Comparison<T>) and supply your own comparison:
private static int CompareListItems(List<Object> x, List<Object> y)
{
return Convert.ToInt32(y[1]).CompareTo(Convert.ToInt32(x[1]));
}
private static void sortL1Descending(ref List<List<Object>> L1)
{
L1.Sort(CompareListItems);
}
public static double bubblesort( double [] testgrades, int grades)
{
double[] sorted = new double[grades];
for (int i = 0; i < testgrades.Length; i++)
for (int j = 1; j < testgrades.Length - 1; j++)
{
if (testgrades[j] > testgrades[j + 1])
{
double tmp = testgrades[j];
testgrades[j] = testgrades[j + 1];
testgrades[j + 1] = tmp;
}
return testgrades;
}
The error says can return type double[] to double.
Also saying no return value and not letting me use the name bubble sort for the new method
You have to options:
public static void bubblesort(ref double [] testgrades, int grades)
. ...
// return testgrades <-- don't return anything, testgrades it's already sorted
or:
public static double[] bubblesort(ref double [] testgrades, int grades)
//... everything else remains the same, just change the signature
I made a tile map class, that only contains the data and methods to get or set tiles.
Now I have the problem, that I want to make a tile map renderer.
But I thing its not very fast to call the methods GetTile(int layerIndex, int x, int y); to iterate threw the tiles and draw them.
So I want to give the possibility to get the full array with all data.
In this case tiledMapData.
But the problem is, that I want that someone cant change the values of the array, because I want make events for changing tiles for physics.
How I can do this.
public class TiledMap
{
public int LayerCount
{
get;
private set;
}
public int TileCountX
{
get;
private set;
}
public int TileCountY
{
get;
private set;
}
public int TotalTileCount
{
get;
private set;
}
private int[,] tiledMapData;
public TiledMap(int layerCount, int tileCountX, int tileCountY)
{
LayerCount = layerCount;
TileCountX = tileCountX;
TileCountY = tileCountY;
TotalTileCount = TileCountX * TileCountY;
tiledMapData = new int[LayerCount, TotalTileCount];
for (int layerIndex = 0; layerIndex < TotalTileCount; layerIndex++)
{
for (int tileIndex = 0; tileIndex < TotalTileCount; tileIndex++)
{
tiledMapData[layerIndex, tileIndex] = 0;
}
}
}
public int GetTile(int layerIndex, int x, int y)
{
return tiledMapData[layerIndex, y * TileCountX + x];
}
public void SetTile(int layerIndex, int x, int y, int tileType)
{
tiledMapData[layerIndex, y * TileCountX + x] = tileType;
}
}
And generally, how you would design a tilemap 100 x 100 tiles 16 bit graphics and destroy able/build able tiles, how handle physics player interaction and so on....?
Maybe someone know good tutorials(The language is not important)
Thanks for helping me :)
Okay I have to reject this, it makes a difference event when not using Length directly.
const int countX = 100;
const int countY = 100;
const int countLayer = 5;
TiledMap tm = new TiledMap(countLayer, countX, countY);
const int testRuns = 10000;
Console.WriteLine("Run 1, start");
DateTime start1 = DateTime.Now;
for (int test = 0; test < testRuns; test++)
{
for (int i = 0; i < countLayer; i++)
{
for (int j = 0; j < countX; j++)
{
for (int k = 0; k < countY; k++)
{
int data = tm.GetTile(i, j, k);
data++;
}
}
}
}
DateTime end1 = DateTime.Now;
Console.WriteLine(String.Format("Run 1, time: {0}", end1-start1));
Console.WriteLine("Run 2, start");
DateTime start2 = DateTime.Now;
for (int test = 0; test < testRuns; test++)
{
for (int i = 0; i < countLayer; i++)
{
for (int j = 0; j < countX; j++)
{
for (int k = 0; k < countY; k++)
{
int data = tm.DirectArray[i, k*countX + j];
data++;
}
}
}
}
DateTime end2 = DateTime.Now;
Console.WriteLine(String.Format("Run 1, time: {0}", end2 - start2));
Console.ReadLine();
The array access variant performed much better. Still not sure if it would when you use some kind of read only array. So make sure you check it out.
I have a multidimensional array, which I want to initialize in a simple and fast way:
double[,,] arr = new double[4,5,6];
// doesn't work by design
foreach(double d in arr)
d = ... ; // my initialization value
This obviously doesn't works. But I would like to have a generic function for setting all array values to a choosen default. With own classes, I could write a special constructor, but with value types I've no real idea. With C++, I could access all items in a linear way with one for loop, but in C# I think I've to use as much for loops as I have dimensions. I've no better solution at the moment ( or I'm using unsafe code and pointer arithmetics, which would probably work.).
Is there a more elegant way for doing this ?
Not quite sure if it's what you want, but the following extension method will allow you to initialise every value in an array, regardless of the number of dimensions.
public static class ArrayExtensions
{
public static void Set<T>(this Array array, T defaultValue)
{
int[] indicies = new int[array.Rank];
SetDimension<T>(array, indicies, 0, defaultValue);
}
private static void SetDimension<T>(Array array, int[] indicies, int dimension, T defaultValue)
{
for (int i = 0; i <= array.GetUpperBound(dimension); i++)
{
indicies[dimension] = i;
if (dimension < array.Rank - 1)
SetDimension<T>(array, indicies, dimension + 1, defaultValue);
else
array.SetValue(defaultValue, indicies);
}
}
}
Use like so:
int[, ,] test1 = new int[3, 4, 5];
test1.Set(1);
int[,] test2 = new int[3, 4];
test2.Set(1);
int[] test3 = new int[3];
test3.Set(1);
I would strongly recommend using a 1D array, and map the values sequentially. You will need to convert from indeces i, j, k, ... into the proper array index, which is done with the Que() function below, part of a generic array class SeqArray<T>.
// Test code first
class Program
{
static void Main(string[] args)
{
/* 3 pages, of a 4x2 matrix
*
* |16 17|
* | 8 9|19|
* | 0 1|11|21|
* | 2 3|13|23|
* | 4 5|15|
* | 6 7|
*
* shown above are the sequential indeces for a rank 3 array
*/
SeqArray<double> arr = new SeqArray<double>(3, 4, 2);
// Initialize values to squential index "num"
int num = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 2; k++)
{
arr[i, j, k] = num++;
}
}
}
// Check that the array values correspond to the index sequence
num = 0;
for (int i = 0; i < 3 * 4 * 2; i++)
{
Trace.Assert(arr.InnerArray[i] == num++);
}
// Initialize with value=π
arr = new SeqArray<double>(Math.PI, 4, 5, 6);
}
}
public class SeqArray<T>
{
T[] values;
int[] lengths;
public SeqArray(params int[] lengths)
{
this.lengths = lengths;
int N = 1;
for (int i = 0; i < lengths.Length; i++)
{
N *= lengths[i];
}
values = new T[N];
}
public SeqArray(T value, params int[] lengths) : this(lengths)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = value;
}
}
public int[] Lengths { get { return lengths; } }
public int Size { get { return values.Length; } }
internal T[] InnerArray { get { return values; } }
public int Que(params int[] indeces)
{
// Check if indeces are omited like arr[4] instead of arr[4,0,0]
if (indeces.Length < lengths.Length)
{
// Make a new index array padded with zeros
int[] temp = new int[lengths.Length];
indeces.CopyTo(temp, 0);
indeces = temp;
}
// Count the elements for indeces
int k = 0;
for (int i = 0; i < indeces.Length; i++)
{
k = lengths[i] * k + indeces[i];
}
return k;
}
public T this[params int[] indeces]
{
get { return values[Que(indeces)]; }
set { values[Que(indeces)] = value; }
}
}
Here is a non-recursive version alternative to that posted by Andy Holt above:
public static void SetAll<T>(this Array array, T value)
{
var sizes = new int[array.Rank];
sizes[array.Rank - 1] = 1;
for (var d = array.Rank - 2; d >= 0; d--)
{
sizes[d] = array.GetLength(d + 1)*sizes[d + 1];
}
for (var i = 0; i < array.Length; i++)
{
var remainder = i;
var index = new int[array.Rank];
for (var d = 0; d < array.Rank && remainder > 0; d++)
{
index[d] = remainder / sizes[d];
remainder -= index[d]*sizes[d];
}
array.SetValue(value, index);
}
}