Home > Software design >  How should I make this logic in C?
How should I make this logic in C?

Time:10-21

There is this linear system given by the following 2d array:

1.0  0.0  -1.0  -4.9  -5.9   -6.9   -7.9
0.0  1.0   2.0   4.4   5.4    6.4    7.4
0.0  0.0   0.0   5.7   5.7   -3.3   -3.3
0.0  0.0   0.0   2.9   2.9    2.9    2.9
0.0  0.0   0.0   7.0  -1.0   -3.0   -3.0
0.0  0.0 -20.0 -65.9 -89.9 -100.9  128.9

Whenever I get a 0 in my main diagonal (when row equals column), I want to change the order of the rows, so there's no zeroes on my main diagonal.

In this case, the row 2(counting from 0) should be traded with row 5 (also counting from 0) because with this, there is no 0s on the main diagonal.

I'm already doing that, but I'm "deleting" the first line and appending it on the end of the linear system. How should I make this logic to know where to exactly trade the rows?

The code is as follows:

void change_order(double linear[6][7], unsigned int qty) {
    double aux[100];

    // dynamically create an array of pointers of size `m`
    double **matrix = (double **)malloc((qty   1) * sizeof(double *));

    // dynamically allocate memory of size `n` for each row
    for (int r = 0; r < qty  1; r  ) {
        matrix[r] = (double *)malloc((qty   1) * sizeof(double));
    }
 
    for (int i = 0; i < qty; i  ) {
        for (int j = 0; j < qty  1; j  ) {
            if (i == 0)
                aux[j] = linear[i][j];
        }
    }

    for (int i = 0; i < qty; i  ) {
        for (int j = 0; j < qty  1; j  ) {
            matrix[i][j] = linear[i][j];
        }
    }

    remove_line(matrix, 0, qty);

    for (int i = 0; i < qty; i  ) {
        for (int j = 0; j < qty  1; j  ) {
            linear[i][j] = matrix[i][j];
        }
    }

    for (int i = 0; i < qty; i  ) {
        for (int j = 0; j < qty  1; j  ) {
            if (i == qty- 1) {
                linear[i][j] = aux[j];
            }
        }
    }
}
void remove_line(double ** linear, int row, unsigned int qty) {
    qty--;

    free(linear[row]);
    while (row < qty) {
        linear[row] = linear[row   1];
        row  ;
    }
}
int main() {
    double matrix[][7] = {
        {1.0,  0.0,  -1.0,  -4.9,  -5.9,   -6.9,  -7.9},
        {0.0,  1.0,   2.0,   4.4,   5.4,    6.4,   7.4},
        {0.0 , 0.0,   0.0,   5.7,   5.7,   -3.3,  -3.3},
        {0.0 , 0.0,   0.0,   2.9,   2.9,    2.9,   2.9},
        {0.0 , 0.0,   0.0,   7.0,  -1.0,   -3.0,  -3.0},
        {0.0 , 0.0, -20.0, -65.9, -89.9, -100.9, 128.9}
    };

    change_order(matrix, 6);
}

Example input:

0   3   2   28
4   0   2   24
2   3   0   16
4   2   1    0  

Can be exchanged for:

4   0   2   24
2   3   0   16
4   2   1    0  
0   3   2   28

CodePudding user response:

If I'm understanding your requirements correctly, would you please try the following:

#include <stdio.h>
#include <stdlib.h>
#define ROWS 6
#define COLS 7

/*
 * search for a trade line to be swapped below the n'th row
 */
int search_trade(double matrix[][COLS], int qty, int n)
{
    for (int i = n   1; i < qty; i  ) {
        if (matrix[i][n] != 0.0) {
            return i;   // i'th row is a nice trade
        }
    }
    return -1;          // not found
}

/*
 * swap m'th row and n'th row
 */
void swap(double matrix[][COLS], int qty, int m, int n)
{
    int j;
    double tmp;
    for (j = 0; j < qty   1; j  ) {
        tmp = matrix[m][j];
        matrix[m][j] = matrix[n][j];
        matrix[n][j] = tmp;
    }
}

void change_order(double linear[][COLS], int qty) {
    for (int i = 0; i < qty; i  ) {
        if (linear[i][i] == 0.0) {                      // found 0 in the diagonal
            int k = search_trade(linear, qty, i);       // search for the trade row
            if (k < 0) {                                // no applicable trade
                fprintf(stderr, "cannot find the row to swap. abort.\n");
                exit(1);
            } else {
                swap(linear, qty, i, k);                // swap i'th row and k'th row
            }
        }
    }
}

/*
 * print the elements of the matrix
 */
void matprint(double matrix[][COLS], int qty)
{
    for (int i = 0; i < qty; i  ) {
        for (int j = 0; j < qty   1; j  ) {
            printf("%.2f%s", matrix[i][j], j == qty ? "\n" : " ");
        }
    }
    printf("\n");
}

int main() {
    double matrix[][COLS] = {
        {1.0,  0.0,  -1.0,  -4.9,  -5.9,   -6.9,  -7.9},
        {0.0,  1.0,   2.0,   4.4,   5.4,    6.4,   7.4},
        {0.0 , 0.0,   0.0,   5.7,   5.7,   -3.3,  -3.3},
        {0.0 , 0.0,   0.0,   2.9,   2.9,    2.9,   2.9},
        {0.0 , 0.0,   0.0,   7.0,  -1.0,   -3.0,  -3.0},
        {0.0 , 0.0, -20.0, -65.9, -89.9, -100.9, 128.9}
    };

    matprint(matrix, ROWS);

    change_order(matrix, ROWS);

    matprint(matrix, ROWS);
}

Output:

0.00 1.00 2.00 4.40 5.40 6.40 7.40
0.00 0.00 0.00 5.70 5.70 -3.30 -3.30
0.00 0.00 0.00 2.90 2.90 2.90 2.90
0.00 0.00 0.00 7.00 -1.00 -3.00 -3.00
0.00 0.00 -20.00 -65.90 -89.90 -100.90 128.90

1.00 0.00 -1.00 -4.90 -5.90 -6.90 -7.90
0.00 1.00 2.00 4.40 5.40 6.40 7.40
0.00 0.00 -20.00 -65.90 -89.90 -100.90 128.90
0.00 0.00 0.00 2.90 2.90 2.90 2.90
0.00 0.00 0.00 7.00 -1.00 -3.00 -3.00
0.00 0.00 0.00 5.70 5.70 -3.30 -3.30

You'll see the 2nd row and the 5th row are swapped.
The main concept is:

  • Seek the diagonal elements for value 0.
  • If 0 is found, search for a trade row which has a non-zero value in the same column.
  • If no trade rows are found, the program prints an error message and aborts.
  • If a trade row is found, swap the rows.

[Edit]
Answering your comment, the code assumes the count of cols == count of rows 1. As your provided example has 4x4 matrix, let me add an extra column as:

    double matrix[][COLS] = {
        {0, 3, 2, 28, -1},
        {4, 0, 2, 24, -1},
        {2, 3, 0, 16, -1},
        {4, 2, 1, 0, -1}
    };

(Please note the value -1 is a dummy value and meaningless so far.)
And modify the #define lines as:

#define ROWS 4
#define COLS 5

Then the program will output:

0.00 3.00 2.00 28.00 -1.00
4.00 0.00 2.00 24.00 -1.00
2.00 3.00 0.00 16.00 -1.00
4.00 2.00 1.00 0.00 -1.00

4.00 0.00 2.00 24.00 -1.00
0.00 3.00 2.00 28.00 -1.00
4.00 2.00 1.00 0.00 -1.00
2.00 3.00 0.00 16.00 -1.00

which shows the rows are properly rearranged having no 0 values in the diagonal. (BTW your expected result breaks having 0 in the diagonal in the last row.)

CodePudding user response:

**You can make a main function like as follows: //after passing the linear function

int i,j, temp; // declare i and j as global variables**
      
for(i=0,i<qty 1,i  )
  {
  for (j=0;j<qty 1;j  )
    {
    if(i==j & matrix[i][j]==0)
      {
        remove_line;
        temp = i;
        break;
       }
    }
 }         // here we are looking for a zero in the diagonal.
  for (;i<qty 1;i  )
 {
  if(matrix[i][j]!=0)
 {
   matrix[temp][j] = linear[i][j]
 }
} 
// **here we are increasing the rows till we get a non zero element and then 
interchanging the values.**
  • Related