| | | |

Algoritmos e Programação I

5 Arranjos e matrizes

Material disponível para compra: e-book apostila. Consulte outras formas de colaboração aqui!

5.4 Matrizes

Arranjos multidimensionais222Consulte a Seção 5.3 fornecem uma estrutura adequada para a representação de matrizes em computador. Uma matriz A, assim como um arranjo bidimensional, é uma coleção de valores organizados de forma retangular, por exemplo, a matriz A=[ai,j]i,j=1n,m tem a forma

A=[a1,1a1,2a1,ma2,1a2,2a2,man,1an,2an,m] (5.109)

Seus elementos ai,j são organizados por eixos, o eixo das linhas (axis=0) e o eixo das colunas (axis=1).

Exemplo 5.4.1.

O sistema linear

2x1-x2+x3=-3 (5.110a)
-x1+x2+3x3=6 (5.110b)
x1+3x2-3x3=2 (5.110c)

pode ser escrito na seguinte forma matricial

A𝒙=𝒃, (5.111)

onde A=[ai,j]i,j=13,3 é a matriz de coeficientes

A=[2-11-11313-3], (5.112)

o vetor dos termos constantes 𝒃=(b1,b2,b3) é

𝒃=(-3,6,2), (5.113)

enquanto que o vetor das incógnitas é 𝒙=(x1,x2,x3). No seguinte código, usamos numpy.array para alocamos a matriz dos coeficientes A e o vetor dos termos constantes 𝒃.

1import numpy as np
2# matriz dos coefs
3A = np.array([[2, -1, 1],
4              [-1, 1, 3],
5              [1, 3, -3]])
6# vet termos consts
7b = np.array([-3, 6, 2])

5.4.1 Operações matriciais

Embora úteis para a representação de matrizes, arranjos bidimensionais não são equivalentes a matrizes. Em arranjos, as operações aritméticas elementares (+, -, *, /, etc.) são operações elemento-a-elemento, para matrizes a multiplicação não é assim calculada e a divisão não é definida.

Multiplicação matricial

No NumPy, as funções numpy.dot, numpy.matmul ou o operador @ podem ser usados para computar a multiplicação matricial.

Exemplo 5.4.2.

Considerando as matrizes

A=[2-11-11313-3], (5.114)
B=[1-12110] (5.115)

temos

AB=[1-34242] (5.116)

Usando o NumPy, temos

1import numpy as np
2
3A = np.array([[2, -1, 1],
4              [-1, 1, 3],
5              [1, 3, -3]])
6
7B = np.array([[1, -1],
8              [2, 1],
9              [1, 0]])
10
11AB = A@B
12print(f'AB =\n {AB}')
13
14AB = np.matmul(A, B)
15print(f'AB =\n {AB}')
16
17AB = np.dot(A, B)
18print(f'AB =\n {AB}')
Exemplo 5.4.3.

Consideramos o sistema linear introduzido no Exemplo 5.4.1. Vamos verificar que sua solução é x1=-1, x2=2 e x3=1. Equivalentemente, temos que

A𝒙=𝒃, (5.117)

com 𝒙=(-1,2,1). Isto é, se 𝒙 é solução do sistema, então é nulo o resíduo 𝒃-A𝒙, i.e.

𝒃-A𝒙=𝟎. (5.118)

Ou equivalentemente, 𝒃-A𝒙=0.

1import numpy as np
2import numpy.linalg as npla
3
4# matriz dos coefs
5A = np.array([[2, -1, 1],
6              [-1, 1, 3],
7              [1, 3, -3]])
8# vet termos consts
9b = np.array([-3, 6, 2])
10# solução
11x = np.array([-1, 2, 1])
12
13# verificação
14res = b - A@x
15norm_res = npla.norm(res)
16print(f solução? {np.isclose(norm_res, 0.)}')

Matriz transposta

Por definição, a transposta de uma matriz A=[ai,j]i,j=1n,m é a matriz AT=[aj,i]j,i=1m,n, i.e. a matriz B obtida de A pela permutação de suas linhas com suas colunas. No NumPy, a transposta de um arranjo bidimensional pode ser calculado com a função numpy.transpose, com o método numpy.ndarray.transpose ou com o atributo numpy.ndarray.T.

Exemplo 5.4.4.

Uma matriz é dita ser simétrica, quando A=AT. Observamos que é simétrica a matriz

A=[2-11-11313-3], (5.119)
1import numpy as np
2A = np.array([[2, -1, 1],
3              [-1, 1, 3],
4              [1, 3, -3]])
5
6trans_A = np.transpose(A)
7print(f'A^T =\n {trans_A}')
8
9trans_A = A.transpose()
10print(f'A^T =\n {trans_A}')
11
12trans_A = A.T
13print(f'A^T =\n {trans_A}')
14
15print(f simétrica? {np.allclose(A, A.T)}')

Agora, não é simétrica a matriz

B=[1-12110]. (5.120)
1import numpy as np
2B = np.array([[1, -1],
3              [2, 1],
4              [1, 0]])
5print(B.T)

Determinante

Por definição, o determinante de uma matriz A=[ai,j]i,j=1n,n é o escalar

det(A)=|a1,1a1,2a1,na2,1a2,2a2,nan,1an,2an,n| (5.125)
:=σSnsign(σ)a1,σ1a2,σ2an,σn (5.126)

onde Sn é o conjunto de todas as permutações de 1,2,,n e sign(σ) é o sinal (ou assinatura) da permutação σSn. Para matrizes 2×2, temos

det(A)=|a1,1a1,2a2,1a2,2| (5.129)
=a1,1a2,2-a1,2a2,1. (5.130)

Enquanto que no caso de matriz 3×3, temos

det(A)=|a1,1a1,2a1,3a2,1a2,2a2,3a3,1a3,2a3,3| (5.134)
=a1,1a2,2a3,3 (5.135)
  +a1,2a2,3a3,1 (5.136)
  +a1,3a2,1a3,2 (5.137)
  -a1,3a2,2a3,1 (5.138)
  -a1,1a2,3a3,2 (5.139)
  -a1,2a2,1a3,3. (5.140)

A função numpy.linalg.det do NumPy pode ser usado para computar o determinante de um arranjo.

Exemplo 5.4.5.

O determinante

det(A)=|2-11-11313-3| (5.144)
=-28 (5.145)
1import numpy as np
2import numpy.linalg as npla
3A = np.array([[2, -1, 1],
4              [-1, 1, 3],
5              [1, 3, -3]])
6
7detA = npla.det(A)
8print(f'det(A) = {detA}')

5.4.2 Aplicação: método de Cramer

O Método de Cramer333Gabriel Cramer, 1704 - 1752, matemático suíço. Fonte: Wikipédia: Gabriel Cramer. usa de determinantes para o cálculo da solução de sistemas lineares. Dado um sistema linear n×n

A𝒙=𝒃 (5.146)

denotamos a matriz dos coeficientes por

A=[𝒂1𝒂2𝒂n], (5.147)

onde 𝒂i denota a i-ésima coluna de A. Vamos denotar por Ai a matriz obtida de A substituindo 𝒂i pelo vetor dos termos constantes 𝒃, i.e.

Ai:=[𝒂1𝒂i-1𝒃𝒂i+1𝒂n] (5.148)

O método consiste em computar a solução 𝒙=(x1,x2,,xn) com

xi=det(Ai)det(A), (5.149)

para cada i=1,2,,n.

Exemplo 5.4.6.

Vamos resolver o sistema linear dado no Exemplo 5.4.1. Sua forma matricial é

A𝒙=𝒃 (5.150)

com matriz dos coeficientes

A=[2-11-11313-3], (5.151)

e vetor dos termos constantes

𝒃=(-3, 6, 2). (5.152)

Para aplicação do Método de Cramer, calculamos

det(A):=|2-11-11313-3| (5.156)
=-28 (5.157)

e das matrizes auxiliares

det(A1):=|-3-1161323-3| (5.161)
=28 (5.162)
det(A2):=|2-31-16312-3| (5.166)
=-56 (5.167)
det(A3):=|2-1-3-116132| (5.171)
=-28 (5.172)

Com isso, obtemos a solução

x1=det(A1)det(A)=-1, (5.173)
x2=det(A2)det(A)=2, (5.174)
x3=det(A3)det(A)=1. (5.175)
1import numpy as np
2import numpy.linalg as npla
3# matriz dos coefs
4A = np.array([[2, -1, 1],
5              [-1, 1, 3],
6              [1, 3, -3]])
7# vet termos consts
8b = np.array([-3, 6, 2])
9
10# det(A)
11detA = npla.det(A)
12print(f'det(A) = {detA}')
13
14# matrizes auxiliares
15## A1
16A1 = np.copy(A)
17A1[:,0] = b
18detA1 = npla.det(A1)
19print(f'det(A1) = {detA1}')
20
21## A2
22A2 = np.copy(A)
23A2[:,1] = b
24detA2 = npla.det(A2)
25print(f'det(A2) = {detA2}')
26
27## A3
28A3 = np.copy(A)
29A3[:,2] = b
30detA3 = npla.det(A3)
31print(f'det(A3) = {detA3}')
32
33# solução
34x = np.array([detA1/detA, detA2/detA, detA3/detA])
35print(f'x = {x}')

5.4.3 Exercícios

E. 5.4.1.

Complete as lacunas.

  1. a)

    Usualmente, matrizes são computacionalmente modeladas como arrays multidimensionais.

  2. b)

    A operação de multiplicação matricial entre dois arrays pode ser feita com o operador @ ou com o método numpy.matmul.

  3. c)

    A transposta de um numpy.array bidimensional pode ser obtida com o atributo .T ou o método numpy.transpose.

  4. d)

    O submódulo numpy.linalg contém o método det para a computação do determinante de um numpy.array.


a) arrays; b) @; c) .T; d) numpy.linalg

E. 5.4.2.

Aloque com numpy.array e imprima as seguintes matrizes:

  1. a)
    A=[-127-3] (5.176)
  2. b)
    B=[-1247-3-5] (5.177)
  3. c)
    C=[-1247-3-5296] (5.178)
  4. d)
    D=[-1247-3-52961-11] (5.179)

1import numpy as np
2# a)
3A = np.array([[-1, 2],
4              [7, -3]])
5print(f'A =\n {A}')
6# b)
7B = np.array([[-1, 2, 4],
8              [7, -3, -5]])
9print(f'B =\n {B}')
10# c)
11C = np.array([[-1, 2, 4],
12              [7, -3, -5],
13              [2, 9, 6]])
14print(f'C =\n {C}')
15# d)
16D = np.array([[-1, 2, 4],
17              [7, -3, -5],
18              [2, 9, 6],
19              [1, -1, 1]])
20print(f'D =\n {D}')
E. 5.4.3.

Aloque as seguintes matrizes com numpy.array

A=[-1247-3-5] (5.180)

e

B=[1-12305]. (5.181)

Então, compute e imprima o resultado das seguintes operações matriciais

  1. a)

    A+B

  2. b)

    A-B

  3. c)

    2A


1import numpy as np
2A = np.array([[-1, 2, 4],
3              [7, -3, -5]])
4B = np.array([[1, -1, 2],
5              [3, 0, 5]])
6# a)
7ApB = A + B
8print(f'A+B =\n {ApB}')
9# b)
10AmB = A - B
11print(f'A-B =\n {AmB}')
12# c)
13_2A = 2*A
14print(f'2A =\n {_2A}')
E. 5.4.4.

Aloque as seguintes matrizes numpy.array:

A=[-1247-3-5] (5.182)

e

B=[1-13025]. (5.183)

Então, compute e imprima o resultado das seguintes operações matriciais:

  1. a)

    AB

  2. b)

    BA

  3. c)

    BT

  4. d)

    ATBT


1import numpy as np
2A = np.array([[-1, 2, 4],
3              [7, -3, -5]])
4B = np.array([[1, -1],
5              [3, 0],
6              [2, 5]])
7# a)
8AB = A @ B
9print(f'AB =\n {AB}')
10# b)
11BA = B @ A
12print(f'BA =\n {BA}')
13# c)
14Bt = B.T
15print(f'B^T =\n {Bt}')
16# d)
17AtBt = A.T @ B.T
18print(f'A^T.B^T =\n {AtBt}')
E. 5.4.5.

Escreva a forma matricial A𝒙=𝒃 do seguinte sistema linear

-x1+2x2-2x3=6 (5.184a)
3x1-4x2+x3=-11 (5.184b)
x1-5x2+3x3=-10 (5.184c)

Use numpy.array para alocar a matriz dos coeficientes A e o vetor dos termos constantes 𝒃. Então, verifique quais dos seguintes vetores é solução do sistema

  1. a)

    𝒙=(1,-1,-2)

  2. b)

    𝒙=(-1,-2,1)

  3. c)

    𝒙=(-2,1,-1)


1import numpy as np
2A = np.array([[-1, 2, -2],
3              [3, -4, 1],
4              [1, -5, 3]])
5b = np.array([6, -11, -10])
6# c)
7x = np.array([-2, 1, -1])
8print(f solução? {np.allclose(A@x, b)}')
E. 5.4.6.

Calcule e compute o determinante das seguintes matrizes

  1. a)
    A=[-127-3] (5.185)
  2. b)
    B=[-1241-3-5206] (5.186)
  3. c)
    C=[-12417-3-5-120101-11-2] (5.187)

1import numpy as np
2import numpy.linalg as npla
3# a)
4A = np.array([[-1, 2],
5              [7, -3]])
6detA = npla.det(A)
7print(f'det(A) =\n {detA}')
8# b)
9B = np.array([[-1, 2, 4],
10              [1, -3, -5],
11              [2, 0, 6]])
12detB = npla.det(B)
13print(f'det(B) =\n {detB}')
14# c)
15C = np.array([[-1, 2, 4, 1],
16              [-1, -3, -5, -1],
17              [2, 0, 1, 0],
18              [1, -1, 1, -2]])
19detC = npla.det(C)
20print(f'det(C) =\n {detC}')
E. 5.4.7.

Use o Método de Cramer para computar a solução do sistema dado no E.5.4.5. Verifique sua solução com a do método numpy.linalg.solve.


Dica: 𝒙=(-2,1,-1).

E. 5.4.8.

Desenvolva sua própria função Python para a computação do determinante de uma matriz A n×n.


Dica: use a função intertools.permutations para obter um iterador sobre as permutações.


Envie seu comentário

Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!

Opcional. Preencha seu nome para que eu possa lhe contatar.
Opcional. Preencha seu e-mail para que eu possa lhe contatar.
As informações preenchidas são enviadas por e-mail para o desenvolvedor do site e tratadas de forma privada. Consulte a política de uso de dados para mais informações.

Licença Creative Commons
Este texto é disponibilizado nos termos da Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional. Ícones e elementos gráficos podem estar sujeitos a condições adicionais.

Pedro H A Konzen
| | | |