Dear nice and smart people, would you mind sharing with me why my code is unable to swap rows for a matrix please? When I run the code, both rows become the same, omg.
entries[i] is the dynamic array storing the elements in the matrix.
Elements are stored row by row, from left to right.
i.e. in a 3X3 matrix, entries[2] is 3rd element on the 1st row,
entries[3] is 1st element on the 2nd row
n = number of rows in matrix
m = number of columns in matrix
void Matrix::SwapRows(int i, int j) {
double* temp;
temp = new double[n * m];
double* temp2;
temp2 = new double[n * m];
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= m; b++) {
if (a == i) {
temp[(j - 1) * m + b - 1] = entries[(j - 1) * m + b - 1];
entries[(a - 1) * m + b - 1] = temp[(j - 1) * m + b - 1];
}
if (a == j) {
temp2[(i - 1) * m + b - 1] = entries[(i - 1) * m + b - 1];
entries[(a - 1) * m + b - 1] = temp2[(i - 1) * m + b - 1];
}
}
}
delete temp;
delete temp2;
}
THanx to Jesper Juhl, swap does the trick. Correct method is as per below. Thank you Jesper!
void Matrix::SwapRows(int i, int j) {
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= m; b++) {
if (a == i) {
swap (entries[(a - 1) * m + b - 1], entries[(j - 1) * m + b - 1]);
}
}
}
}
Related
I'm trying to rewrite the main loop in a physics simulation and split the workload between more threads.
It calls dostuff on every unique pair of indices and looks like this:
for (int i = 0; i < n - 1; ++i)
{
for (int j = i + 1; j < n; ++j)
{
dostuff(i, j);
}
}
I came up with two options:
//#1
//sqrt is implemented as binary search on ints, floors the result
for (int x = 0; x < n * (n - 1) / 2; ++x)
{
int i = (1 + sqrt(1 + 8 * x)) / 2;
int j = x - i * (i - 1) / 2;
dostuff(i, j);
}
//#2
for (int x = 0; x < n * n; ++x)
{
int i = x % n;
int j = x / n;
if (i < j)
dostuff(i, j);
}
And for each option, there is corresponding thread loop using shared atomic counter:
//#1
while(int x = counter.fetch_add(1) < n * (n - 1) / 2)
{
int i = (1 + sqrt(1 + 8 * x)) / 2;
int j = x - i * (i - 1) / 2;
dostuff(i, j);
}
//#2
while(int x = counter.fetch_add(1) < n * n)
{
int i = x % n;
int j = x / n;
if (i < j)
dostuff(i, j);
}
My question is, what is the best way to share the workload of the main loop between threads for n < 10^6?
EDIT:
//dostuff
Element& a = elements[i];
Element& b = elements[j];
glm::dvec3 r = b.getPosition() - a.getPosition();
double rv = glm::length(r);
double base = G / (rv * rv);
glm::dvec3 dir = glm::normalize(r);
glm::dvec3 bd = dir * base;
accelerations[i] += bd * b.getMass();
accelerations[j] -= bd * a.getMass();
Your work is a triangle. You want to.divide the triangle into k distinct pieces.
If k is a power of 2 you can do this:
a
a a
b c d
b c d d
Each of those regions are equal in size.
I have to to create a dynamic adjacency list graph based off of a 2D array(40x20) of 0's and 1's. The graph will have an edge, if two elements of the array that are exactly 1 distance apart (up, down, left or right only, no diagonals) are both 1's, which would look like that: (Each vertex has an unique number equal to: (ROW)*(MAX_COLUMNS) + (COLUMN))
0 1 2 3 4
0 0 0 1 1 1
1 1 1 1 0 1
2 1(1)0 1 1
3 0 1 0 1 0
4 1 1 0 1 0
Adjacencylist[(2*5)+1] = {6 , 10 , 16}
Etc.
So far I've managed to create a list for only one of the neighbours of a given vertex, but I've got no idea how to add the next neighbour to the neighbour before, nor do I know how to make it work on the edges of the graph(When there is only 2 or 3 neighbours) Here's the full code: https://ideone.com/r2JRrf , and below is just the part that is problematic to me.
struct Wierzcholek {
Wierzcholek* next;
int wartosc;
}
Wierzcholek* p;
Wierzcholek** TablicaList = new Wierzcholek * [LiczbaWierzcholkow];
for (int i = 0; i < LiczbaWierzcholkow; i++)
TablicaList[i] = nullptr;
for (int i = 1; i < 40-1; i++)
for (int j = 1; j < 20-1; j++)
{
if (MacierzGrafu[i][j] == 0) continue;
else
{
if (MacierzGrafu[i - 1][j] == 1)
{
p = new Wierzcholek;
p->wartosc = (((i-1) * 20) + j);
p->next = TablicaList[(i * 20) + j];
TablicaList[(i * 20) + j] = p;
}
/* Here are the algorithms for creating up,down and right neighbours,
// however I'm unable to make them all work together
if (MacierzGrafu[i][j - 1] == 1)
{
p = new Wierzcholek;
p->wartosc = ((i * 20) + j - 1);
p->next = TablicaList[(i * 20) + j];
TablicaList[(i * 20) + j] = p;
}
if (MacierzGrafu[i + 1][j] == 1)
{
p = new Wierzcholek;
p->wartosc = (((i+1) * 20) + j);
p->next = TablicaList[(i * 20) + j];
TablicaList[(i * 20) + j] = p;
}
if (MacierzGrafu[i - 1][j - 1] == 1)
{
p = new Wierzcholek;
p->wartosc = ((i * 20) + j + 1);
p->next = TablicaList[(i * 20) + j];
TablicaList[(i * 20) + j] = p;
}
/*
How should I steer the pointers to make the graph stable(and usable for DFS)?
On a sidenote, how do I give the function a formal parameter that is Wierzcholek** Vertex. Any help is greatly appreciated, as I'm fairly new to programming and only really beginning to understand the beautiful complexity of pointers and dynamically allocated memory.
Turns out the part of code i commented actually works, so for whatever reason if you need a adjacency list for a simple rectangle Graph, that you want to later search with DFS or BFS you could use my code implemented here(I know the field of use of this code is not really broad but it may come handy to someone struggling in school/college like i did)[Also you would need to add some sort of restrictions for borders of this graph, or just make every "edge" as in GraphMatrix[0][k],GraphMatrix[k][0],GraphMatrix[MAX][k] and GraphMatrix[k][MAX] (k being an integer < MAX) a 0 because you might get memory leaks as the elements out of scope might be unaccesible to you]:
//GraphMatrix is rectangle matrix composed of 0's and 1's
struct Vertex {
Vertex* next;
int value;
}
Vertex* p;
Vertex** AdjacencyList = new Vertex * [NumberOfVertices];
for (int i = 0; i < NumberOfVertices; i++)
AdjacencyList[i] = nullptr;
for (int i = 1; i < 40-1; i++) // In this case 40 and 20 were the height and
for (int j = 1; j < 20-1; j++) // width of my rectangular graph
{
if (GraphMatrix[i][j] == 0) continue;
else
{
if (GraphMatrix[i - 1][j] == 1)
{
p = new Vertex;
p->value= (((i-1) * 20) + j);
p->next = AdjacencyList [(i * 20) + j];
AdjacencyList [(i * 20) + j] = p;
}
if (GraphMatrix[i][j - 1] == 1)
{
p = new Vertex;
p->value= ((i * 20) + j - 1);
p->next = AdjacencyList [(i * 20) + j];
AdjacencyList [(i * 20) + j] = p;
}
if (GraphMatrix[i + 1][j] == 1)
{
p = new Vertex;
p->value= (((i+1) * 20) + j);
p->next = AdjacencyList [(i * 20) + j];
AdjacencyList [(i * 20) + j] = p;
}
if (GraphMatrix[i - 1][j - 1] == 1)
{
p = new Vertex;
p->value= ((i * 20) + j + 1);
p->next = AdjacencyList [(i * 20) + j];
AdjacencyList [(i * 20) + j] = p;
}
my codes does not work for Gauss Elimination for Matrix. The core code is ok, but it seems to be missing some final touch which I honestly dont know. Would be great if someone can point out the mistake.
Basically when I input a square 3x3 Matrix filled with 3s, I get back (3, 3, 3, 0, -3, -3, 0, 0, 3) but it should be (3, 3, 3, 0, 0, 0, 0, 0, 0)
n is number of rows of matrix and m is number of columns.
All elements of matrix are stored in a SINGLE DIMENSION array called entries[i]
My code below for GaussElimination basically starts with placing the row with the largest first element on the top row. Then after that I just delete the elements right below the top elements.
Matrix Matrix::GaussElim() const {
double maxEle;
int maxRow;
for (int i = 1; i <= m; i++) {
maxEle = fabs(entries[i-1]);
maxRow = i;
for (int k = i+1; k <= m; k++) {
if (fabs(entries[(k - 1) * n + i - 1]) > maxEle) {
maxEle = entries[(k - 1) * n + i - 1];
maxRow = k;
}
}
for (int a = 1; a <= m; a++) {
swap(entries[(i - 1) * m + a - 1], entries[(maxRow - 1) * m + a - 1]);
}
for (int b = i + 1; b <= n; b++) {
double c = -(entries[(b - 1) * m + i - 1]) / entries[(i - 1) * m + i - 1];
for (int d = i; d <= n; d++) {
if (i == d) {
entries[(b - 1) * m + d - 1] = 0;
}
else {
entries[(b - 1) * m + d - 1] = c * entries[(i - 1) * m + d - 1];
}
}
}
}
Matrix Result(n, m, entries);
return Result;
}
For starters, I'd suggest to drop the habit of starting the loops at 1 instead of the more idiomatic 0, it would simplify all of the formulas.
That said, this statement
else {
entries[(b - 1) * m + d - 1] = c * entries[(i - 1) * m + d - 1];
// ^^^
}
Looks suspicious. There should be a += (or a -=, depending on how you choose the sign of the pivot).
Another source of unexpected results is the way chosen to calculate the constant c:
double c = -(entries[(b - 1) * m + i - 1]) / entries[(i - 1) * m + i - 1];
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Even in case of partial pivoting, that value could be zero (or too small), due to the nature of the starting matrix, like in the posted example, or to numerical errors. In those cases, it would be preferable to just zero out all the remaining elements of the matrix.
I am trying to create triangular grid with sorted triangles in OpenGL. I have vertices buffer and indices buffer. I was partialy succesfull, but one half of grid is rendering wrong as you can see on screenshot. I cant figure out why is that.
My code is here
float[] vertices = new float[2 * rows * columns];
int counter = 0;
for(int r = 0; r <rows; r++){
for(int c = 0; c < columns; c++){
vertices[counter ++] = (float)r / (rows-1);
vertices[counter ++] = (float)c / (columns -1);
}
}
int[] indices = new int[4 * (rows) * (columns)];
int counter = 0;
for(int r = 0; r < rows; r++){
for(int c =0; c <= columns; c++){
if(r % 2 == 0){
if(c == columns){
indices[counter ++] = (c-1) + (r+1)*columns;
indices[counter ++] = (c-1) + (r+1)*columns;
}else{
indices[counter ++] = c + r * columns;
indices[counter ++] = c + (r+1) * columns;
}
}else{
if(c == columns){
indices[counter ++] = (columns) - c + (r +1) * columns;
indices[counter ++] = (columns) - c + (r +1) * columns;
}else{
indices[counter ++] = (columns - 1) - c + (r + 1) * columns;
indices[counter ++] = r*columns + (columns-1) - c;
}
}
}
}
for (int r = 0; r < rows - 1; r++) { is what you actually want.
You are using (r+1) rows while looping from r = 0 to r = (rows - 1), effectively ending up in a non-existent row filled with zeroes.
So this is not a «half of the grid», it`s just the final row of triangles.
And BTW, 4 * rows * columns is too much for a list of triangle strip indices with 2 additional degenerate triangles between strips; 2 * (columns + 1) * (rows - 1) shall be enough.
I overloaded operator * which multiplying 2D arrays. I have some problems with multiplying, don't understand exactly an indexes when I am multiplying.
Here's some declarations:
int *const e; //pointer to the memory storing all integer elements of A
const int row, column; //r and c are the numbers of rows and columns respectively
And some code:
A A::operator*(const A& matrix)const
{
MAT result(matrix.row, matrix.column);
if (column == matrix.row)
{
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < matrix.column; j++)
{
result.e[j*row + i] = 0;
for (int k = 0; k < column; k++)
{
result.e[j*row + i] += e[j*row + k] * matrix.e[k*row + column];
}
}
}
}
return result;
}
I know that I need 3 loops, I think I have some problems in
result.e[j*row + i] += e[j*row + k] * matrix.e[k*row + column];
Do you have any clue ? You can write me some ideas how can I figure out it myself, because I want to understand it. Thanks
Your line
result.e[j*row + i] += e[j*row + k] * matrix.e[k*row + column];
is broken. The product P of two matrices A (dim M,N) and B (dim N,P) has it's coefficient in position (i,j) defined by the following :
Pi,j = sum(k = 1..N, ai,k . bk,j).
Thus the line mentioned above should be :
result.e[j*row + i] += e[j*row + k] * matrix.e[k*row + i];