How to make one matrix run inside another using functions?

Asked

Viewed 924 times

1

I have two functions, one belongs to a 10x10 matrix and the other to a 3x3 matrix. I need to make the 3x3 matrix run inside the 10x10 matrix.

How do I do that?

From now on I thank anyone who can help.

Example: this is the 3x3 matrix:

void conv(int p[3][3]){
    int i, j;
    for(i=0;i<3;i++){
        for(j=0;j<3;j++){
            p[i][j]=p[i][j]*p[i][j];
        }
    }
}

void img(int mat[lin][col]){
    int i, j, contador=1;
    for(i=0;i<lin;i++){
        for(j=0;j<col;j++){

        }
    }
}

I need the conv function, which has a matrix, to be inserted into the img function, where there is another matrix. I need it to go through all elements of the img matrix by changing the original value.

  • 1

    Set "belongs to the matrix" and "run inside the other one", please.

  • Example: this is matrix 3x3: void convulacao(int p[3][3]){ int i, j; for(i=0;i<3;i++){ for(j=0;j<3;j++){ p[i][j]=p[i][j]*p[i][j];&#xA; }&#xA; } }

  • Just below the question, there is the button editar. Use it to post the codes you wrote. It will be easier to understand the problem.

  • p[i][j]=p[i][j]*p[i][j]; - this will only replace each element of the matrix by the value of its square.

  • I don’t know if I got it right. Going through a 10x10 matrix and extracting 3x3 pieces is easy. But what do you want to do with these 3x3 pieces?

  • Okay, I think I get it. I’m going to try to formulate an answer.

  • I edited the question.. actually it’s a bit of extensive code, I really needed to make one matrix run inside the other.. I only abbreviated the code to make it easier..

Show 2 more comments

1 answer

1


Extracting a 3x3 chunk from a 10x10 matrix and passing it to a function has some complications. The first is that in matrices, all elements are stored in memory sequentially. That is, in a 10x10 matrix we have the 100 elements in sequence. In a 3x3 matrix, we will have the 9 elements in sequence. However, in a 3x3 matrix within a 10x10, the 9 desired 3x3 elements will not be in sequence, and therefore cannot be simply represented in the form of a simple pointer, which requires a more elaborate technique.

In addition, there are still some problems regarding that the processing of a submatrix may end up interfering in the processing of another submatrix when the matrix elements are changed. For example, imagine you have the following matrix (I will use 5x5 to make it easier to understand):

A B C D E
F G H I J
K L M N O
P Q R S T
U V W X Y

If when processing the ABC-FGH-KLM submarine, you replace the G with a Z, the subsequent submarine will be BCD-ZHI-LMN instead of BCD-GHI-LMN.

There are several possible solutions to this problem. I think the simplest solution to this problem would be:

  • Represent the submatrix as main matrix indices.

  • Use two different matrices, one for data reading and one for draft for writing. At the end, the draft matrix can be copied over the original and then discarded, or else the original be discarded and keep the resulting.

If I understand correctly, you want a function that receives another function as a parameter in order to apply it over the whole matrix. In object-oriented programming languages and with generic types such as C++ and Java, this is much easier to do. This is also possible in C, but with scary syntax. Here’s the result:

#include <stdio.h>

void conv(int largura, int altura, int linha, int coluna, int original[altura][largura], int resultante[altura][largura]) {
    int i, j;
    if (linha >= altura - 2 || coluna >= largura - 2) return;
    for (i = linha; i < linha + 3; i++) {
        for (j = coluna; j < coluna + 3; j++) {
            resultante[i][j] = original[i][j] * original[i][j];
        }
    }
}

void operar(int largura, int altura, int original[altura][largura], int resultante[altura][largura], void (*op)(int largura, int altura, int linha, int coluna, int original[largura][altura], int resultante[altura][largura])) {
    int i, j;
    for (i = 0; i < altura; i++) {
        for (j = 0; j < largura; j++) {
            op(largura, altura, i, j, original, resultante);
        }
    }
}

void imprimir(int largura, int altura, int original[altura][largura]) {
    int i, j;
    for (i = 0; i < altura; i++) {
        for (j = 0; j < largura; j++) {
            printf("%5d ", original[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int entrada[5][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}, {16, 17, 18, 19, 20}, {21, 22, 23, 24, 25}};
    int saida[5][5];
    operar(5, 5, entrada, saida, conv);
    imprimir(5, 5, entrada);
    printf("\n");
    imprimir(5, 5, saida);
}

See here working on ideone. Here is the output generated:

    1     2     3     4     5 
    6     7     8     9    10 
   11    12    13    14    15 
   16    17    18    19    20 
   21    22    23    24    25 

    1     4     9    16    25 
   36    49    64    81   100 
  121   144   169   196   225 
  256   289   324   361   400 
  441   484   529   576   625 

Note that the function conv It’s almost the same as what you gave. The difference is that the width and height of the matrix are explained in the function parameters as well as the row and column of the 3x3 block to be operated. There are also two matrices, one of which will be read and the other of which will be written.

The function operar is the scariest and has a horribly long and complicated signature. In particular the void (*op)(int largura, int altura, int linha, int coluna, int original[largura][altura], int resultante[altura][largura]) is a function pointer. The void is the return type of the function. The (*op) indicates that this is a function pointer called op and the content after that corresponds to the types of parameters of that function. The code within the function operar however it is quite simple, it just runs through the matrices calling the function op in all positions.

Finally, in the function main we have it:

operar(5, 5, entrada, saida, conv);

This means that the function conv shall be executed for each position of 5x5 matrices entrada and saida. This way, you can encode other functions similar to conv, provided they have the same parameters and return void and use it in function operar likewise.

Ah, and an important observation. That only makes sense if you really need submarines in your role conv or similar. If you are working element by element without the processing of one element interfering with the other, all this would be much simpler. At the moment, its function conv could be rewritten like this:

void conv(int largura, int altura, int linha, int coluna, int original[altura][largura], int resultante[altura][largura]) {
    resultante[linha][coluna] = original[linha][coluna] * original[linha][coluna];
}
  • Thanks for the explanation Victor! I will try to apply this in solving my problem. As soon as I finish, insert here.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.