VB - Operações com Matrizes
Neste artigo vamos tirar do baú alguns conceitos matemáticos sobre matrizes e mostrar como criar uma interface a mais amigável possível para efetuar operações com matrizes.
Para não complicar demais o código eu vou focar somente as operações de soma , subtração , multiplicação e produto escalar de um número por uma matriz usando números inteiros. Se você detesta matemática não deixe de ler o artigo pois nele vou mostrar como permitir a entra de dados no controle MSFlexGrid.
Os conceitos Matemáticos
Eu particularmente gosto de matemática , e, creio que todo bom programador também deve gostar , afinal conceitos matemáticos estão intimamente relacionados com a arte de programar. Assim o conceito de matrizes é fundamental para qualquer programador. Vamos então recordar os conceitos aprendidos na escola.
a-) O que é uma matriz ?
Matriz de ordem
m x n : Para os nossos
propósitos, podemos considerar uma matriz como sendo uma tabela
rectangular de números reais (ou complexos) dispostos em m
linhas e n colunas. Diz-se então que a matriz tem ordem m
x n (lê-se: ordem m por n)
Exemplos:
A = ( 1 0 2 -4 5) Uma linha e cinco colunas ( matriz de ordem 1 por 5 ou 1
x 5)
B é uma matriz de quatro linhas e uma coluna, portanto de ordem 4 x 1.
Notas:
1) se m = n , então dizemos que a matriz é
quadrada de ordem n.
Exemplo:
A matriz X é uma matriz quadrada de ordem 3x3 , dita simplesmente de ordem 3 .
2) Uma matriz A de ordem m x n , pode ser indicada como A = (aij )mxn , onde aij é um elemento da linha i e coluna j da matriz.
Assim , por exemplo , na matriz X do exemplo anterior , temos a23 = 2 , a31 = 4 , a33 = 3 , a31 = 4 , a3,2 = 5 ,
Vamos ver a seguir o conceito de produto de matrizes.
b-)
Produto de matrizes
Para que exista o produto de duas matrizes A e B ,
o número de
colunas de A , tem de ser igual ao número de linhas de B.
Amxn x Bnxq = Cmxq
Se a matriz A tem ordem m x n e a matriz B tem ordem n x q , a matriz produto C tem ordem m x q .
Vamos mostrar o produto de matrizes com um exemplo:
Onde L1C1 é o produto escalar dos elementos da linha 1 da
1ª matriz pelos elementos da coluna1 da segunda matriz, obtido
da seguinte forma:
L1C1 = 3.2 + 1.7 = 13. Analogamente,
teríamos para os outros elementos:
L1C2 = 3.0 + 1.5 = 5
L1C3 = 3.3 + 1.8 = 17
L2C1 = 2.2 + 0.7 = 4
L2C2 = 2.0 + 0.5 = 0
L2C3 = 2.3 + 0.8 = 6
L3C1 = 4.2 + 6.7 = 50
L3C2 = 4.0 + 6.5 = 30
L3C3 = 4.3 + 6.8 = 60, e, portanto, a matriz
produto será igual a:
Observe que o produto de uma matriz de ordem 3x2 por outra 2x3, resultou na matriz produto P de ordem 3x3.
Nota: O produto de matrizes é uma operação não comutativa, ou seja: A x B # B x A
c-) Soma e Subtração de matrizes
Com os conceitos acima creio que não precisarei entrar em mais detalhes , assim , para que a operação de adição e subtração entre duas matrizes seja possível , elas devem ser da mesma ordem , ou seja, deverá possuir o mesmo número de linhas e de colunas.
Assim se a ordem da matriz A for m x n e a da matriz B p x q , para que a soma seja possível teremos que ter m=p e n=q.
A soma ou subtração entre duas matrizes é realizada entre a soma dos elementos da linha 1 da 1ª matriz pelos elementos da linha 1 da segunda matriz e assim sucessivamente.
Resumindo temos que A soma de duas matrizes A e B, ambas de ordem m x n, é uma matriz C de mesma ordem, em que cada elemento é a soma dos elementos correspondentes em A e B.
d-) Produto escalar de um número por uma matriz
Multiplicar uma matriz A por um número "k" é obter uma matriz B de mesma ordem de A, formada pelos elementos de a multiplicados por k.
VB - Matrizes
Vou aproveitar a oportunidade para recordar alguns dos conceitos sobre 'arrays' no VB. Vamos lá...
No VB uma 'array' ( matriz ou arranjo) faz referência a um conjunto de variáveis de mesmo nome que identificamos por um indíce numérico com um limite inicial e um final. Todos os elementos da matriz possui o mesmo tipo de dados. Um 'array' pode ter um tamanho fixo ou pode variar dinamicamente.
Um 'array' de tamanho fixo é criado usando o comando Dim usando a seguinte sintaxe: Dim NomeMatriz(indice)
Ex: Dim Matriz(5) - A matriz terá os elementos : Matriz(0), Matriz(1), Matriz(2) , Matriz(3) , Matriz(4)
Geralmente o índice inicial é zero ( podemos alterar isto usando o comando Option Base 1 no módulo da aplicação) , mas podemos definir o índice incial e final na declaração do array: Dim Matriz( 1 to 20).
Para criar uma matriz dinâmica basta declarar a matriz sem definir os limites: ex: Dim Matriz()
Em seguida , quando precisar , basta redimensionar a matriz usando o comando Redim. Ex: Redim Matriz(20)
O comando Redim todos os valores armazenados na matriz são perdidos , se quiser , manter os valores já atribuídos ao array deve usar a cláusula : Preserve. Ex: Redim Preserve Matriz(20)
A interface com o usuário
Se você chegou até aqui parabéns , vamos agora mostrar como criar um programa no Visual Basic , é claro , que efetue as operações com matrizes acima descritas. A primeira coisa que vou mostrar será a interface com o usuário , ou seja os formulários usados na aplicação.
Nosso projeto terá os seguintes formulários :
Vou mostrar agora as três visões da aplicação ; primeiro as visões do formulário frmmatrizes.frm:
-
frmmatrizes.frm - Esta é a visão principal da aplicação para as operações somar/subtrair e multplicar , nela temos além das caixas de texto onde o usuário informa o número de linhas e de colunas para cada matriz , dois controles MSFlexgrid onde o usuário irá digitar os valores para cada célula da matriz. |
|
-
frmmatrizes.frm -Esta é a visão do produto escalar de um número inteiro por uma matriz. |
|
-
frmresultado.frm - Este formulário exibe o resultado das operações entre as matrizes. |
O codigo da aplicação
Não vou comentar todo o código da aplicação , vou me ater somente na entrada de dados do controle MSFlexgrid e no código que realiza as operações de soma , subtração , produto e produto escalar.
- A primeira coisa a fazer é escolher a operação e a seguir informar o número de linhas e colunas para cada matriz. Ao clicar no botão - informar valores - o sistema cria automaticamente via controle msflexgrid uma grade com o mesmo número de linhas e colunas informadas pelo usuário.(lembrando que no caso do msflexgrid o índice inicial é zero). O código que faz esta operação é dado a seguir:
Private Sub define_tamanho_matrizA() grdgrid1.Rows = Int(txtlinhas1(1).Text) grdgrid1.Cols = Int(txtcolunas1(2).Text) For i = 0 To grdgrid1.Rows - 1 grdgrid1.RowHeight(i) = 300 Next For j = 0 To grdgrid1.Cols - 1 grdgrid1.ColWidth(j) = 700 Next End Sub |
O código acima - Define a grade usando os valores informados para o número de linhas e colunas , e também define o tamanho de cada célula da grade.
- O código de entrada de dados (ver abaixo) via controle MSFlexgrid. O usuário clica na célula e digita os valores e tecla ENTER para ir para a próxima célula.
'entrada de valores na Matriz A - grdgrid1 Private Sub grdGrid1_KeyPress(KeyAscii As Integer) 'se o caractere for um numero, ponto ou sinal de menos então permite a entrada If KeyAscii > 47 And KeyAscii < 58 Or KeyAscii = 46 Or KeyAscii = 45 Or _ KeyAscii = 43 Or KeyAscii = 105 Or KeyAscii = 106 Then grdgrid1.Text = grdgrid1.Text + Chr(KeyAscii) cnt = cnt + 1 ElseIf KeyAscii = 8 Then 'se for um retrocesso, remove o último caractere entrado If cnt > 0 Then cnt = cnt - 1 grdgrid1.Text = Left(grdgrid1, cnt) End If 'se pressione enter entao move para a proxima celula ElseIf KeyAscii = 13 Then If grdgrid1.Col < grdgrid1.Cols - 1 Then 'move para direita ate alcancar o fim da linha grdgrid1.Col = grdgrid1.Col + 1 Else grdgrid1.Col = 0 If grdgrid1.Row < grdgrid1.Rows - 1 Then 'entao vai para proxima linha grdgrid1.Row = grdgrid1.Row + 1 Else grdgrid1.Row = 0 'quando alcanca a ultima linha volta para primeira celula grdgrid1.Col = 0 End If End If ElseIf KeyAscii = 67 Or KeyAscii = 99 Then ' se pressionear c ou C limpa a celula grdgrid1.Text = "" ElseIf KeyAscii = 61 Then KeyAscii = 43 grdgrid1.Text = grdgrid1.Text + Chr(KeyAscii) cnt = cnt + 1 End If End Sub |
O código captura a tecla que o usuário digitou e verifica se ela tem um valor válido (número, sinal de -/+) ou se o usuário teclou o retrocesso.(KeyAscii = 8) ; neste caso é permitido a correção do valor informado.
Para limpar a célula basta digitar o caractere C ou c. (KeyAscii = 67 Or KeyAscii = 99)
Ao digitar a tecla - ENTER- (Keyscii = 13) o foco muda para a célula seguinte até o final do grid.
Este código permite que o usuário informe os valores em cada célula do MSFLexgrid ; cada célula representa uma linha e coluna da matriz. Abaixo uma visão da entrada de dados em uma matriz 4x3 usando o controle MSFlexgrid.
-
Quando o usuário informa o número de linhas e colunas e
clica no botão informar valores , um grid com 4 linhas e
3 colunas e exibido para entrada de dados. - na parte superior temos a indicação da posição célula representando um elemento da linha i e da coluna j. |
Após informar os valores para cada matriz basta clicar no botão para realizar a operação selecionada. Vejamos agora o código de cada operação.
- Produto de matrizes
Public Function ProdutoMatriz() Dim i As Integer Dim j As Integer Dim k As Integer Dim m As Integer Dim produto As Single Dim resultado As Single ReDim MatrizResultado(grdgrid1.Rows, grdgrid2.Cols) For i = 0 To grdgrid1.Rows - 1 For k = 0 To grdgrid2.Cols - 1 resultado = 0 For j = 0 To grdgrid1.Cols - 1 If grdgrid1.TextMatrix(i, j) = "" Then grdgrid1.TextMatrix(i, j) = 0 End If If grdgrid2.TextMatrix(j, k) = "" Then grdgrid2.TextMatrix(j, k) = 0 End If produto = Val(grdgrid1.TextMatrix(i, j)) * Val(grdgrid2.TextMatrix(j, k)) resultado = resultado + produto Next j MatrizResultado(i, k) = resultado Next k Next i frmresultado.Show End Function |
Redimensionamos a variável MatrizResultado para conter o número de linhas da matriz A e o número de colunas da matriz B - ReDim MatrizResultado(grdgrid1.Rows, grdgrid2.Cols)
Em um loop percorremos as linhas e colunas e multiplicamos os elementos da primeira linha pelos elementos da primeira coluna sucessivamente ; e armazenamos o resultado na variável produto ; a cada mudança de linha atribuimos o valor acumulado á variável - MatrizResultado(i,j).
- Soma de matrizes
O codigo para soma de matrizes é dado a seguir , para subtração basta mudar o sinal da operação de + para - .
Public Function SomarMatriz() Dim i As Integer Dim j As Integer ReDim MatrizResultado(grdgrid1.Rows, grdgrid2.Cols) For i = 0 To grdgrid1.Rows - 1 For j = 0 To grdgrid2.Cols - 1 resultado = 0 If grdgrid1.TextMatrix(i, j) = "" Then grdgrid1.TextMatrix(i, j) = 0 End If If grdgrid2.TextMatrix(i, j) = "" Then grdgrid2.TextMatrix(i, j) = 0 End If resultado = Val(grdgrid1.TextMatrix(i, j)) + Val(grdgrid2.TextMatrix(i, j)) MatrizResultado(i, j) = resultado Next j Next i frmresultado.Show End Function |
O codigo acima soma os elementos de cada linha da matriz A com os elementos de cada linha da Matriz B. O resultado é armazenado na variável - MatrizResultado(i,j).
- Produto de um escalar por uma matriz
Public Function EscalarMatriz() Dim i As Integer Dim j As Integer ReDim MatrizResultado(grdgrid1.Rows, grdgrid2.Cols) For i = 0 To grdgrid1.Rows - 1 For j = 0 To grdgrid1.Cols - 1 resultado = 0 If grdgrid1.TextMatrix(i, j) = "" Then grdgrid1.TextMatrix(i, j) = 0 End If If grdgrid2.TextMatrix(i, j) = "" Then grdgrid2.TextMatrix(i, j) = 0 End If resultado = (Val(grdgrid1.TextMatrix(i, j)) * Val(txtescalar.Text)) MatrizResultado(i, j) = resultado Next j Next i frmresultado.Show End Function |
O código acima multiplica da elemento da matriz A pelo número informado e armazena o resultado na variável MatrizResultado(i,j).
Obs: Perceba que o código abaixo aparece em todas as operações ; ele apenas garante que se alguma célula não possuir um valor o valor atribuído será o número zero.
If grdgrid1.TextMatrix(i, j) = "" Then grdgrid1.TextMatrix(i, j) = 0 End If If grdgrid2.TextMatrix(i, j) = "" Then grdgrid2.TextMatrix(i, j) = 0 End If |
- Apresentando o resultado da operação
No final de cada operação o formulário - frmresultado.frm - é invocado para exibir o resultado, vejamos o seu código:
Private Sub Form_Load() grdgrid3.Rows = frmmatrizes.grdgrid1.Rows grdgrid3.Cols = frmmatrizes.grdgrid2.Cols For i = 0 To grdgrid3.Rows - 1 grdgrid3.RowHeight(i) = 300 Next For j = 0 To grdgrid3.Cols - 1 grdgrid3.ColWidth(j) = 700 Next For i = 0 To grdgrid3.Rows - 1 For j = 0 To grdgrid3.Cols - 1 grdgrid3.TextMatrix(i, j) = MatrizResultado(i, j) Next j Next i End Sub |
Neste código primeiro é criado o grid com o número de linhas da Matriz A e o número de colunas da Matriz B:
grdgrid3.Rows =
frmmatrizes.grdgrid1.Rows
grdgrid3.Cols = frmmatrizes.grdgrid2.Cols
a seguir formatamos o tamanho de cada célula e atribuímos os valores armazenados na matriz MatrizResultado(i,j) a cada célula do grid.
For i = 0 To grdgrid3.Rows - 1 For j = 0 To grdgrid3.Cols - 1 grdgrid3.TextMatrix(i, j) = MatrizResultado(i, j) Next j Next i |
Abaixo vamos mostra a sequência de uma operação de produto de matrizes :
O resultado será uma matriz da ordem : 5 x 4 conforme abaixo :
Neste artigo além de aprender alguns conceitos matemáticos importantes também aprendemos outra forma de usar o MSFlexGrid para entrada de dados.
Agora acabei , até o próximo artigo sobre VB e a matemática...!!! (o projeto completo esta no super CD VB)
José Carlos Macoratti