Multiply a matrix by a vector

Asked

Viewed 740 times

0

I need to make a program that multiplies a 3x3 matrix by a vector 3, and store the result in a new vector. But I can’t get the result and the problem is probably multiplication.

 public  static  void  main ( String [] args ) {
    int[] vetor = new int[3];
    int[] vetor2 = new int[3];
    int[][] matriz = new int[3][3];
    int i;
    int j;

    //Atribui um valor
    
    Scanner input = new Scanner(System.in);
    System.out.println("Numeros do vetor: ");
    for(i = 0; i < vetor.length ; i++)
    vetor[i] = input.nextInt();
    System.out.println("Numeros da matriz: ");
    for(i = 0; i < matriz.length ; i++){
        for(j = 0; j < matriz[i].length ; j++)
            matriz[i][j] = input.nextInt();

    }
    input.close();
    
    System.out.println("Tamanho do vetor: " + vetor.length);
    System.out.println("Tamanho da mariz: " + matriz.length);
    
    //Multiplica
    for(i = 0; i < 3; i++){
        for(j = 0; j < 3; j++)
        vetor2[i] = vetor[i] * matriz[i][j];
    }

    //Exibe os valores multiplicados
    System.out.printf("\nValores Multiplicados \n");
    
    for(i = 0; i < 3; i++){
        for(j = 0; j < 3; j++)
        System.out.printf("%d ",vetor2[i]);
        System.out.printf("\n");
    }
}
  • Just for the record that Adriano’s answer is wrong (and the other le314u too). By coincidence it works in some cases, but changes the vector to {1, 2, 3} and it will go wrong: see here that gives {6, 30, 72}, but the correct result is {14, 32, 50}. This happens because it should be used vetor[j] instead of vetor[i] in multiplication. And it also does not consider cases where the matrix is not square. Please see my answer for a more general solution (and correct).

2 answers

0

Given a matrix M x N (M rows and N columns) and a vector with N elements, the result is a vector with M elements, and the algorithm for multiplying the matrix by the vector is:

      matriz A            vetor x           multiplicação (matriz * vetor)
A[1,1] A[1,2] ... A[1,N]   x[1]    A[1,1] * x[1] + A[1,2] * x[2] + ... + A[1,N] * x[N]
A[2,1] A[2,2] ... A[2,N]   x[2]    A[2,1] * x[1] + A[2,2] * x[2] + ... + A[2,N] * x[N]
.                          .                             .
.                          .                             .
.                          .                             .
A[M,1] A[M,2] ... A[M,N]   x[N]    A[M,1] * x[1] + A[M,2] * x[2] + ... + A[M,N] * x[N]

Note that each element of the result is the sum of several operations. But in for that makes multiplication, you are overwriting the value of vetor2[i], instead of adding to the existing value.

Another detail is that you do not need to declare all variables at the beginning of the program. You can declare them closer to where they will be used, and - in my opinion - this makes the code a little clearer (in small codes like this it doesn’t make much difference, but in larger codes it helps a lot). Including the variables of loops may be declared within the for.

And in the specific case of System.in, no need to close it (read more about it here and here).

In short, it would look like this:

int[] vetor = new int[3];
int[][] matriz = new int[3][3];

// ler os dados com o Scanner
...

// quantidade de elementos do resultado = quantidade de linhas da matriz
int[] resultado = new int[matriz.length];
for (int i = 0; i < matriz.length; i++) { // para cada linha da matriz
    for (int j = 0; j < vetor.length; j++) { // cada elemento da linha, multiplicado por um elemento do vetor
        resultado[i] += vetor[j] * matriz[i][j]; // soma ao resultado
    }
}

// não precisa usar printf se não tem variáveis a serem impressas, use println mesmo
System.out.println("\nValores Multiplicados");
for (int n : resultado) { // se eu só quero os valores, não precisa do índice
    System.out.printf("%d ", n);
}

When I initialize the array resultado with new int[matriz.length], by default your elements will already be zero. And I use matriz.length because the size of the result is the number of rows in the matrix.

Then, inside the for, i update the value of each element, adding to the current value (that’s what the operator += makes). Also note that I used vetor[j] (and not vetor[i] as you were doing), so the calculation is correct.

The other answers are using vetor[i] instead of vetor[j], and with that the result is wrong. For example, if the matrix and the vector are:

int[][] matriz = new int[][] {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};
int[] vetor = new int[] { 1, 2, 3 };

The result must be the vector {14, 32, 50} (check here). But the code of the other answers gives {6, 30, 72} (That’s because they’re using vetor[i] instead of vetor[j] in multiplication, but according to the above algorithm, we see that it is the column value that matters in this calculation).

Another detail is that the other answers do not consider the cases where the matrix is not square. For example, if it is {{1, 2, 3}, {4, 5, 6}} (2 rows and 3 columns), the result should be a vector with 2 elements (using the same vector above, the result should be {14, 32}). But one of the answers considered that the result has the same size as the vetor input (ie 3), and with that he will have an extra position - maybe this detail has gone unnoticed because the matrix is square, but either way, both give wrong results, and depending on how you do the code, can even give that mistake.


To print the values, I used a Enhanced for, because if I just want to print the values, I don’t need a variable to control the index (but of course you could also use a for (int i = 0; etc) or Arrays.toString, as suggested the other answer - but this is a detail, because what mattered even here is the correct algorithm to do the multiplication).

Remembering that the code does not verify if the matrix and the vector have compatible dimensions, nor if the matrix is in fact a matrix (if all rows have the same number of columns, because in fact what we have is an array of arrays, and nothing guarantees that they all have the same size, this is something you have to guarantee separately). Of course in this specific case the sizes are correct, but the above code would not serve for something more general that would accept any arrays.

-1

Matrix (3x3) * Vector (3x1) = vector(3x1)

In its code during multiplication in the for Indice j or be the innermost you pass it 3 times and overwrite 3 times saving only the value of vetor2[i] = vetor[i] * matriz[i][2]

When instead of doing :

vetor2[i] = vetor[i] * matriz[i][j];

you should first initialize vector 2 with 0’s and do

vetor2[i] = vetor2[i] + vetor[i] * matriz[i][j];

that is to say

result[0] = (matrix[0][0] * vector[0]) + (matrix[0][1] * vector[1]) + (matrix[0][2] * vector[2])

  • less verbose: vetor2[i] += vetor[i] * matriz[i][j];

  • because you denied my answer?

Browser other questions tagged

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