I am trying to solve LU decomposition with the Doolittle Algorithm – according to this document. Without parallelization, code works fine. However, I would like to make this code run in parallel - trying to make a parallel outer and two inner loops. Unfortunately I am still missing something. If I tried to first make the outer loop run in parallel, I received a bad result.
I tried to detect where there might be a collision. I locked those places afterwards, but I still did not receive the right result. I added them to the copied code as comments. What am I doing wrong, do I need lock out other places?
What´s the right implementation of outer loop?
How would inner loops look like?
Thank you in advance.
Implementation of algorithm (sequential)
//upper triangle
var upper = new double[arr.GetLength(0), arr.GetLength(0)];
//lower triangle
var lower = new double[arr.GetLength(0), arr.GetLength(0)];
//field initialization
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
upper[i, j] = arr[i, j];
for (int j = i + 1; j < n; j++)
lower[j, i] = arr[j, i];
lower[i, i] = 1;
}
for(int i=0; i<n; i++)
{
for (int j = i; j < n; j++)
{
for (int k = 0; k < i; k++)
{
upper[i, j] = upper[i, j] - (lower[i, k] * upper[k, j]);
}
}
for (int j = i + 1; j < n; j++)
{
for (int k = 0; k < i; k++)
{
lower[j, i] = lower[j, i] - (lower[j, k] * upper[k, i]);
}
lower[j, i] = lower[j, i] / upper[i, i];
}
}
Implementation of algorithm (parallel)
//upper triangle
var upper = new double[arr.GetLength(0), arr.GetLength(0)];
//lower triangle
var lower = new double[arr.GetLength(0), arr.GetLength(0)];
//field initialization
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
upper[i, j] = arr[i, j];
for (int j = i + 1; j < n; j++)
lower[j, i] = arr[j, i];
lower[i, i] = 1;
}
//making outer loop parallel
Parallel.For(0, n, (i, state) =>
{
//possibly make this loop parallel also
for (int j = i; j < n; j++)
{
for (int k = 0; k < i; k++)
{
//lower[i,k] is it potential problem?
/*
* I tried this solution
* double a;
* lock(lowerLock){
* a = lower[i,k];
* }
* upper[i, j] = upper[i, j] - (a * upper[k, j])
*/
upper[i, j] = upper[i, j] - (lower[i, k] * upper[k, j]);
}
}
//possibly make this loop parallel also
for (int j = i + 1; j < n; j++)
{
for (int k = 0; k < i; k++)
{
//upper [k,i] is it potential problem?
/*
* I tried this solution
* double b;
* lock(upperLock){
* b = upper[k, i];
* }
* lower[j, i] = lower[j, i] - (lower[j, k] * b);
*/
lower[j, i] = lower[j, i] - (lower[j, k] * upper[k, i]);
}
lower[j, i] = lower[j, i] / upper[i, i];
}
});
sequential right result
Concatenation Upper triangle Lower triangle
2 -1 -2 2 -1 -2 1 0 0
-2 4 -1 0 4 -1 -2 1 0
-2 -1 3 0 0 3 -2 -1 1
parallel bad result
Concatenation Upper triangle Lower triangle
2 -1 -2 2 -1 -2 1 0 0
-2 4 -1 0 4 -1 -2 1 0
-2 -1 3 0 0 10 -->BAD -2 -1 1
EDIT
I tried to lock all the approaches to the fields with one lock. I am aware of loosing all parallelization in this way. However, I wanted to achieve at least the right result, unfortunately without success.
static object mylock = new object();
//making outer loop parallel
Parallel.For(0, n, (i, state) =>
{
for (int j = i; j < n; j++)
{
for (int k = 0; k < i; k++)
{
lock (mylock)
{
upper[i, j] = upper[i, j] - (lower[i, k] * upper[k, j]);
}
}
}
for (int j = i + 1; j < n; j++)
{
for (int k = 0; k < i; k++)
{
lock (mylock)
{
lower[j, i] = lower[j, i] - (lower[j, k] * upper[k, i]);
}
}
lock (mylock)
{
lower[j, i] = lower[j, i] / upper[i, i];
}
}
});
The parallel loops write to the same array, right?
upper[i, j] = upper[i, j] - (lower[i, k] * upper[k, j]);
But it is not defined, when which loop will write to a position in your array. So two loops will NOT write to the same index but read from an index, where the other loop might have already written to.
You can't parallize your algorithm this way.
Related
I don't know what to do, my program is not working
I need to sort a two-dimensional array by the first elements of a row in descending order by rearranging the rows
(need to sort string without sort item)
Let's say I'm given an array:
1 2 3
4 5 6
7 8 9
As a result of the program, I need to get:
7 8 9
4 5 6
1 2 3
`
using System;
namespace BubbleSort
{
internal class Program
{
static void Main(string[] args)
{
//Объявление массива и его размерности
const int n = 3;
int bubble;
int[,] A =
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
};
//Алгоритм пузырьковой сортировки
for (int i = 0; i < n; i++)
{
for(int j = 0; j < n - 1; j++)
{
if (A[i, 0] < A[i++, 0])
{
for(j = 0; j < n-1; j++)
{
bubble = A[i, j];
A[i, j] = A[i, j+1];
A[i, j+1] = bubble;
}
}
}
}
//Вывод массива
for (int y = 0; y < n; y++)
{
for (int x = 0; x < n; x++)
{
Console.Write(A[y, x] + " ");
}
Console.WriteLine();
}
}
}
}
`
From the code in your comments, I'm not sure why you have a nested loop for swapping the values since a single loop will do. I've removed that here.
If you refer to the pseudocode implementation on Wikipedia, you'll see that you need to keep running multiple passes across the array until everything is sorted. You can do this like so:
bool swapped;
do
{
swapped = false; // reset swapped
for (int i = 0; i < n - 1; i++) // loop through all but the last row
{
if (A[i, 0] < A[i + 1, 0]) // determine if this row needs to be swapped with the next row
{
swapped = true; // mark swapped
for (int j = 0; j < n; j++) // swap each item in row i with each item in row i+1
{
int tmp = A[i, j];
A[i, j] = A[i + 1, j];
A[i + 1, j] = tmp;
}
}
}
}
while (swapped); // if we swapped anything, we need to make another pass to ensure the array is sorted
We can also do away with the need for n by using .GetUpperBound(dimension) which returns a value between 0 and n - 1 (where n is the count of items in the array in that dimension). Because the result is effectively n - 1, I've modified the loop conditions slightly:
bool swapped;
do
{
swapped = false;
for (int i = 0; i < A.GetUpperBound(0); i++)
{
if (A[i, 0] < A[i + 1, 0])
{
swapped = true;
for (int j = 0; j <= A.GetUpperBound(1); j++)
{
int tmp = A[i, j];
A[i, j] = A[i + 1, j];
A[i + 1, j] = tmp;
}
}
}
}
while (swapped);
We can also refer to the "Optimizing bubble sort" section of the Wikipedia page and implement that instead, which will make our code run more optimally:
int n = A.GetUpperBound(0); // get the initial value of n
do
{
int newn = 0; // default newn to 0, so if no items are visited, it will remain 0 and the loop will exit
for (int i = 0; i < n; i++)
{
if (A[i, 0] < A[i + 1, 0])
{
for (int j = 0; j <= A.GetUpperBound(1); j++)
{
int tmp = A[i, j];
A[i, j] = A[i + 1, j];
A[i + 1, j] = tmp;
}
newn = i; // store the current (highest) value of i swapped
}
}
n = newn; // set the value of n to the highest value of i swapped
}
while (n > 0); // loop until n == 0
The logic here (as explained on Wikipedia) is that by the end of the first pass, the last item is in the correct position. By the end of the second pass, the second-to-last and last items are in the correct position, and so on. So each time, we can visit one less item. When we have 0 items to visit, we have 0 items to swap, and the sort is complete.
You can see this optimised version in this YouTube visualisation.
I think the line
if (A[i, 0] < A[i++, 0])
should read
if (A[i, 0] < A[i+ 1, 0])
Hello. I have this task to sum the numbers as shown. Tried everything I can, but still not the right answer. Can I have some guidance?
static void Main(string[] args)
{
string input = Console.ReadLine();
int n = (int)char.GetNumericValue(input[0]);
int m = (int)char.GetNumericValue(input[2]);
int[,] matrix = new int[n, m];
int sum = 0;
//fill matrix
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i, j] = (j * 3 + 1) + i * 3;
}
}
for (int i = 0; i < matrix.GetLength(0) - 1; i+=1)
{
for (int j = 0; j < matrix.GetLength(1) - i; j+=1)
{
if (i % 2 == 0)
{
sum += matrix[i, j + i] + matrix[i + 1, j + 1];
}
}
}
Console.WriteLine(sum);
}
I think you would've a easier time hard coding the input (and naming them as "columns" and "rows" instead, much more readable).
What is the expected output? Not sure I'm following this sum. I'm guessing, 297? If so:
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.Write(matrix[i, j] + " ");
if(j == 5) Console.WriteLine();
if (matrix[i, j] % 2 != 0)
{
if (i == 0 || i == matrix.GetLength(0) - 1
|| j == 0 || j == matrix.GetLength(0))
{
sum += (matrix[i, j]);
}
else
{
sum += (matrix[i, j] * 2);
}
}
}
}
I need help for 1-level 5/3 discrete Haar wavelet transform (DWT) source code with c# .
I use this project, and the methods of forward wavelet transform is here :
FWT(double[] data)
{
int h = data.Length >> 1;
for (int i = 0; i < h; i++)
{
int k = (i << 1);
temp[i] = data[k] * s0 + data[k + 1] * s1;
temp[i + h] = data[k] * w0 + data[k + 1] * w1;
}
}
FWT(double[,] data)
{
for (int k = 0; k < 1; k++)
{
for (int i = 0; i < rows / (k+1); i++)
{
for (int j = 0; j < row.Length / (k+1); j++)
row[j] = data[i, j];
FWT(row);
for (int j = 0; j < row.Length / (k+1); j++)
data[i, j] = row[j];
}
for (int j = 0; j < cols / (k+1); j++)
{
for (int i = 0; i < col.Length / (k+1); i++)
col[i] = data[i, j];
FWT(col);
for (int i = 0; i < col.Length / (k+1); i++)
data[i, j] = col[i];
}
}
}
w0 = 0.5; w1 = -0.5;s0 = 0.5;s1 = 0.5;
I searched about this topic in the papers , but I don't understand the algorithm of 5/3 or 9/7 wavelet filters and how can I change this code?
Any help would be much appreciated
You may find it useful: implementation of jpeg2000 decoder in pdf.js.
The implementation of the core of the 5-3 code:
function reversibleTransformFilter(x, offset, length) {
var len = length >> 1;
offset = offset | 0;
var j, n;
for (j = offset, n = len + 1; n--; j += 2) {
x[j] -= (x[j - 1] + x[j + 1] + 2) >> 2;
}
for (j = offset + 1, n = len; n--; j += 2) {
x[j] += (x[j - 1] + x[j + 1]) >> 1;
}
};
Well, this is giving me a real headache. I'm building a matrix determinant function to compute NxN determinant, and I'm using recursion.
The logic is working right but I'm not able to get the final value computed correctly.
Here is my code for Matrix Determinant:
public static double determinant(double[,]array){
double det=0;
double total = 0;
double[,] tempArr = new double[array.GetLength(0) - 1, array.GetLength(1) - 1];
if(array.GetLength(0)==2)
{
det = array[0, 0] * array[1, 1] - array[0, 1] * array[1, 0];
}
else {
for (int i = 0; i <1; i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
if (j % 2 != 0) array[i, j] = array[i, j] * -1;
tempArr= fillNewArr(array, i, j);
det+=determinant(tempArr);
total =total + (det * array[i, j]);
}
}
}
return det;
}
and about fillNewArr method it's just a method to trim the array, method is as follow:
p
ublic static double[,] fillNewArr(double[,] originalArr, int row, int col)
{
double[,] tempArray = new double[originalArr.GetLength(0) - 1, originalArr.GetLength(1) - 1];
for (int i = 0, newRow = 0; i < originalArr.GetLength(0); i++)
{
if (i == row)
continue;
for (int j = 0, newCol=0; j < originalArr.GetLength(1); j++)
{
if ( j == col) continue;
tempArray[newRow, newCol] = originalArr[i, j];
newCol++;
}
newRow++;
}
return tempArray;
}
The method is working as it supposed to "I assume" but the final result is not computed in the right way, why would that be?!
4x4 Array Example:
{2 6 6 2}
{2 7 3 6}
{1 5 0 1}
{3 7 0 7}
Final result should be -168, while mine is 104!
This bit
if (j % 2 != 0) array[i, j] = array[i, j] * -1;
tempArr= fillNewArr(array, i, j);
det+=determinant(tempArr);
total =total + (det * array[i, j]);
uses a variable total that is never used again. It should probably be something like
double subdet = determinant(fillNewArr(array, i, j));
if (j % 2 != 0) subdet *= -1;
det += array[i, j] * subdet;
I have a program that should read in an integer value x from the console, and then print out a multi dimensional. The value of the row i on column j should be i *j. For example: if I input 3, the matrix should look like this:
1 2 3
2 4 6
3 6 9
Now, I have written this code in my Main function:
Console.WriteLine("Input a value: ");
int x = int.Parse(Console.ReadLine());
int[,] arr = new int[x,x];
for (int i = 0; i < x; i--)
{
for (int j = 0; j < x; j++)
{
arr[i, j] = arr[i, j] + arr[i, j];
Console.Write(arr[i, j] + " ");
}
}
Console.ReadLine();
So, when I input 3 from my code, I get the output:
0 0 0
What am I doing wrong here?
You have to change i-- to i++.
Put Console.WriteLine() after inner for loop. It will print a line break after every x numbers to make it loop like matrix.
You're saying The value of the row i on column j should be i *j, but I can't see any i * j in your code. Change your calculations to that: arr[i, j] = i * j;.
That should be it, but because your loops run from 0 to x - 1 and you want result to be as if it was from 1 to x you have to adapt your calculations and make it arr[i, j] = (i + 1) * (j + 1);.
Complete code should be:
Console.WriteLine("Input a value: ");
int x = int.Parse(Console.ReadLine());
int[,] arr = new int[x, x];
for (int i = 0; i < x; i++)
{
for (int j = 0; j < x; j++)
{
arr[i, j] = (i + 1) * (j + 1);
Console.Write(arr[i, j] + " ");
}
Console.WriteLine();
}
Console.ReadLine();
You´re saing that the value of arr[i, j] must be equals to i * j, but you´re not doing it on your code.
change
arr[i, j] = arr[i, j] + arr[i, j];
to
arr[i, j] = (i+1) * (j+1);
another thing that you need to change is that i are being decremented on the for loop, because of this code: i--. change it to i++
Seeing how the int[,] is full of zero's all your doing is adding zero + zero.
Seems like what you really want is this:
int[,] arr = new int[x,x];
for (int i = 0; i < x; i++)
{
for (int j = 0; j < x; j++)
{
arr[i, j] = (i+1) * (j + 1);
Console.Write(arr[i, j] + " ");
}
Console.Write("\r\n");
}
Console.ReadLine();