Você está na página 1de 31

Introdução ao SAS/IML para Álgebra de Matrizes

Introdução ao SAS/IML para Álgebra de Matrizes Escola Superior de Agricultura “Luiz de Queiroz” Departamento de

Escola Superior de Agricultura “Luiz de Queiroz” Departamento de Ciências Exatas - ESALQ/USP Fevereiro de 2002

(versão 3,14)

AntonioAntonioAntonioAntonio AugustoAugustoAugustoAugusto FrancoFrancoFrancoFranco GarciaGarciaGarciaGarcia AntonioAntonioAntonioAntonio FranciscoFranciscoFranciscoFrancisco IemmaIemmaIemmaIemma

Introdução ao SAS/IML para Álgebra de Matrizes

Esse texto destina-se aos alunos do curso de verão de Álgebra de Matrizes do Departamento de Ciências Exatas da ESALQ/USP, visando auxiliar na resolução dos exercícios propostos e fornecendo ao mesmo tempo subsídios para a utilização de um dos programas computacionais mais empregados na Estatística: o SAS (Statistical Analysis System).

Optou-se por apresentar as possíveis aplicações do módulo IML mantendo a mesma seqüência do texto usado em aula, de modo a complementá-lo. Leitores interessados em maiores detalhes poderão consultar o livro SAS/IML Software: Usage and Reference, Version 6, First Edition, Cary, NC: SAS Institute Inc., 1989. 501pp. (6th printing, December 1995), além de outras publicações do referido instituto.

• Por ter finalidades didáticas, os programas aqui citados foram elaborados de forma a facilitar o entendimento do assunto, não visando exclusivamente aplicações práticas ou análise de dados. Supõe-se contudo que esta forma de abordagem propiciará aos leitores com interesse aplicado os subsídios necessários para o desenvolvimento de seus próprios programas.

• Críticas e sugestões, bem como correção de eventuais erros no material, serão bem recebidas.

ConsideraçõesConsideraçõesConsideraçõesConsiderações sobresobresobresobre oooo SAS/IMLSAS/IMLSAS/IMLSAS/IML

sobresobresobresobre oooo SAS/IMLSAS/IMLSAS/IMLSAS/IML 1 Considerações sobre o SAS/IML O software SAS/IML

1 Considerações sobre o SAS/IML

O software SAS/IML (Interactive Matrix Language) é uma linguagem de programação muito flexível, tendo como principais vantagens a interatividade com o usuário, a possibilidade de trabalhar com matrizes de forma simples, além da possibilidade do uso de funções pré- programadas e outras procedures do próprio SAS. Os resultados dos comandos podem ser vistos imediatamente ou armazenados para posterior execução, a critério do usuário. Nesse texto, por razões óbvias, será dada ênfase as operações matriciais. No entanto, o SAS/IML é uma linguagem de programação, permitindo que o usuário escreva seus próprios programas.

Operações como inversão de matrizes, obtenção de autovalores e autovetores, etc, podem ser realizadas usando comandos pré-programados, facilitando o trabalho e evitando o uso de algoritmos sofisticados que utilizam várias linhas de programação. O fato dos algoritmos empregados serem amplamente testados e discutidos por usuários do mundo todo permite que os resultados obtidos sejam muito confiáveis. Além disso, o SAS/IML faz uso muito eficiente dos recursos do computador, facilitando o trabalho com matrizes de grandes dimensões.

As sessões do IML iniciam-se com o comando "proc iml;" e finalizam-se com o comando "quit;". Uma matriz é definida entre chaves ({}), sendo que as vírgulas indicam as mudanças de linhas. Um primeiro programa:

proc iml;

a={3 -1

2,

2 -2

3,

4 1 -4};

x=inv(a);

print x;

quit;

X

0.3333333

-0.133333 0.0666667

1.3333333

-1.333333 -0.333333

0.6666667

-0.466667 -0.266667

Esse programa permite a obtenção da matriz X, que é a inversa de A. O comando PRINT solicita a visualização da matriz X. Vale ressaltar que, ao usar o comando QUIT, a sessão do IML é encerrada e as matrizes e variáveis criadas são apagadas da memória RAM.

DefinindoDefinindoDefinindoDefinindo matrizesmatrizesmatrizesmatrizes

matrizesmatrizesmatrizesmatrizes 2 Definindo matrizes O objeto fundamental sobre o qual

2 Definindo matrizes

O objeto fundamental sobre o qual operam os comandos do IML é uma matriz com linhas e colunas, podendo ser numérica ou alfanumérica. O número máximo de caracteres que um elemento de uma matriz alfanumérica pode apresentar é 32676, sendo que todos os elementos serão armazenados com o mesmo número de caracteres que o maior deles. Os nomes atribuídos as matrizes devem ser válidos no ambiente SAS, seguindo suas regras:

possuir de 1 a 8 caracteres sem espaços e começar com letras, aceitando números a partir do 2º caractere (versões 6.12 e anteriores).

Em versões mais recentes, como a 8.0 e 8.2, os nomes das variáveis podem exceder oito caracteres. É possível criar matrizes com valores perdidos, sendo que os mesmos devem ser indicados por um ponto ("."). Contudo, nem todos os comandos funcionam com matrizes com pontos.

Uma vez definido um nome para a matriz, ele pode ser usado diretamente ou substituído em ações futuras, a critério do usuário, sendo possível inclusive substituir apenas determinados elementos, conforme será visto a seguir. Ao se referir a uma dada matriz, pode ser simplesmente utilizado seu nome, ou ainda especificando seus elementos.

Matrizes com múltiplos elementos são especificadas com o uso de chaves ({ }), sendo que as linhas são separadas por vírgulas. Evidentemente, todas as linhas devem conter o mesmo número de elementos.

Os valores a serem adicionados podem ser:

• Números reais inteiros ou com decimais (notação científica, como 1E-8, é permitida).

• Caracteres alfanuméricos ("strings"), que podem estar entre aspas simples (´ ´) ou duplas (" "), ou até mesmo sem elas, sendo que nesse caso todos os valores serão armazenados com letras maiúsculas.

• Números entre colchetes ( [ ] ) indicam o número de vezes que um dado valor de repete, facilitando a digitação em muitas situações.

Matrizes também podem ser criadas a partir do uso de funções pré-programadas, do comando CALL ou de um programa específico. A seguir, são apresentados exemplos de matrizes com um único elemento (escalares):

proc iml;

a=32;

b=.; c='oi'; d='olá pessoal'; e="ciao"; print a b c d e;

A

B C

D

E

32

. oi olá pessoal ciao

DefinindoDefinindoDefinindoDefinindo matrizesmatrizesmatrizesmatrizes

Já as matrizes com múltiplos elementos são escritas da seguinte maneira:

proc iml; x={10 20 30 40}; y={10, 20, 30, 40}; z={1 2, 3 4, 5 6}; print x y z;

X

Y

Z

10

20

30

40

10

1

2

20

3

4

30

5

6

40

Ou ainda, para caracteres alfanuméricos: este

proc iml;

aa={ abcd

Efgh};

bb={'abcd' 'Efgh'};

print aa bb;

AA

ABCD EFGH abcd Efgh

BB

Pelo fato da matriz AA não apresentar seus elementos entre aspas, eles automaticamente são substituídos por letras maiúsculas. Já para BB, foi respeitada a forma original. Caso seja necessário definir elementos com espaços entre eles, deve-se sempre usar a segunda forma.

Uma forma mais sintética de escrever uma matriz com elementos repetidos é possível indicando o número de vezes que o elemento deve ser repetido, entre colchetes. Por exemplo:

proc iml; resposta={[3] 'Sim', [3] 'Não', [3] 'Talvez'}; print resposta;

RESPOSTA

Sim

Sim

Sim

Não

Não

Não

Talvez Talvez Talvez

DefinindoDefinindoDefinindoDefinindo matrizesmatrizesmatrizesmatrizes

Isso é muito conveniente para construir matrizes com elementos repetidos, como ocorrem com as matrizes de delineamentos experimentais.

Conforme mencionado, uma matriz pode ser redefinida no momento em que o usuário julgar conveniente. A segunda matriz denominada RESPOSTA sobrepõe-se à primeira.

proc iml; resposta={[3] 'Sim', [3] 'Não', [3] 'Talvez'}; resposta={[3] 1, [3] 2, [3] 0}; print resposta;

RESPOSTA

1

1

1

2

2

2

0

0

0

Matrizes também podem ser obtidas como resultado de funções ou expressões, como por exemplo x=inv(a); em que os elementos de X são obtidos pela inversão de A. Há ainda uma opção muito prática, que é a construção de vetores indexados, como apresentado abaixo. Note que é possível inclusive usar a função DO, sendo o último número da função o incremento.

proc iml;

r=1:5;

s=10:5;

t='xyz1':'xyz4';

u=do(-2,1,1);

v=do(-2,1,.5);

print r s t u v;

R

1

2

3

4

5

S

10

9

8

7

6

5

T

xyz1 xyz2 xyz3 xyz4

 

U

-2

-1

0

1

V

-2

-1.5

-1

-0.5

0

0.5

1

DefinindoDefinindoDefinindoDefinindo matrizesmatrizesmatrizesmatrizes

Um comando também útil é o SHOW NAMES, que permite visualizar os atributos de todas as matrizes armazenadas. No caso, tem-se a dimensão, o tipo - numérica ou alfanumérica - e o número de bits para armazenamento.

proc iml;

x={1 1 0,

1 1 0,

1 0 1,

1 0 1};

y={1,

2,

3,

4};

show names;

print x y;

X 4 rows

3 cols num

8

Y 4 rows

1 col

num

8

Number of symbols = 2 (includes those without values)

X

Y

1

1

0

1

1

1

0

2

1

0

1

3

1

0

1

4

Matrizes especiais, como a matriz identidade, possuem comandos específicos para sua obtenção, sendo que o número entre parênteses indica sua dimensão:

proc iml;

identid=i(5);

print identid;

IDENTID

1

0

0

0

0

0

1

0

0

0

0

0

1

0

0

0

0

0

1

0

0

0

0

0

1

Já matrizes com elementos iguais, que podem ser iguais a um (matriz de uns) ou a qualquer outro valor de interesse, são obtidas com a função J.

DefinindoDefinindoDefinindoDefinindo matrizesmatrizesmatrizesmatrizes

proc iml;

uns1_5=j(1,5,1);

uns5_5=j(5,5,1);

quatros=j(3,4,4);

print uns1_5 uns5_5 quatros;

UNS1_5

1 1

1

1

1

 

UNS5_5

QUATROS

1 1

1

1

1

4

4

4

4

1 1

1

1

1

4

4

4

4

1 1

1

1

1

4

4

4

4

1

1

1

1

1

1

1

1

1

1

Para essa função, o primeiro valor dentro dos parênteses indica o número de linhas da matriz a ser criada, o segundo, o de colunas, e o terceiro, o valor que terão todos os elementos.

Outros comandos úteis são os que fornecem a dimensão das matrizes armazenadas, NROW (número de linhas) e NCOL (número de colunas):

proc iml; x={1 2 3, 4 5 6, [3] 9, [2] 1 0}; m=nrow(x); n=ncol(x); print m n x;

M

N

X

4

3

1

2

3

 

4

5

6

9

9

9

1

1

0

Finalizando esta sessão, mencionaremos ainda o comando STORAGE, que permite armazenar (gravar) as matrizes numa biblioteca, permitindo seu uso posterior. Isso pode ser útil nos casos em que os programas são extensos e/ou há limitação de memória do computador. O comando FREE elimina as matrizes da memória RAM.

proc iml;

OperaçõesOperaçõesOperaçõesOperações BásicasBásicasBásicasBásicas

x={1 1 0,

1 1 0,

1 0 1,

1 0 1};

y={1,

2,

3,

4};

store x y; free x y; show storage;

Contents of storage library = WORK.IMLSTOR

Matrices:

X

Y

Modules:

of storage library = WORK.IMLSTOR Matrices: X Y Modules: 3 Operações Básicas A partir desse ponto,

3 Operações Básicas

A partir desse ponto, em função de estarmos sempre apresentando comandos do SAS/IML, não apresentaremos mais os comandos PROC IML e QUIT, necessários para iniciar e encerrar a sessão.

3.1. Adição

A={2 2, 3 4}; B={4 5, 1 0}; SOMA=A+B; print A B soma;

A

B

SOMA

2

2

4

5

6

7

3

4

1

0

4

4

OperaçõesOperaçõesOperaçõesOperações BásicasBásicasBásicasBásicas

3.2. Subtração

DIF=A-B;

print dif;

DIF

-2

-3

2

4

3.3. Multiplicação por Escalar

C=4;

AxC=A*C;

print AxC;

AXC

8

8

12

16

3.4. Multiplicação de Matrizes

AxB=A*B;

print AxB;

AXB

10 10

16 15

3.5. Soma Direta

Para tanto, deve-se utililizar a função BLOCK, que permite realizar a soma direta de um grande número de matrizes.

a={2 2,

4 4};

b={6 6,

8 8};

c=block(a,b);

OperaçõesOperaçõesOperaçõesOperações BásicasBásicasBásicasBásicas

print a b c;

 

A

B

C

2

2

6

6

2

2

0

0

4

4

8

8

4

4

0

0

 

0

0

6

6

0

0

8

8

3.6.

Produto Direto (Kronecker)

 

a={1 0,

 

0

1};

b={1,

2,

3};

 

c1=a@b;

c2=b@a;

c3=a@a;

print a b c1 c2 c3;

 

A

B

C1

C2

1

0

1

1

0

1

0

0

1

2

2

0

0

1

 

3

3

0

2

0

 

0

1

0

2

0

2

3

0

0

3

0

3

C3

1

0

0

0

0

1

0

0

0

0

1

0

0

0

0

1

3.7. Produto de Hadamard

a={1 2,

3 4};

b={4 8,

0 5};

c=a#b;

print c;

OperaçõesOperaçõesOperaçõesOperações BásicasBásicasBásicasBásicas

C

4 16

0 20

3.8. Potência de Matriz Quadrada

É importante ressaltar que matrizes elevadas a números muito grandes podem apresentar como resultado valores com grandes imprecisões numéricas. A potência é obtida como segue.

a={1 2,

3 4};

a2=a**2;

a3=a**3;

inversa=a**(-1);

print a2 a3 inversa;

A2

A3

INVERSA

7

10

37

54

-2

1

15

22

81

118

1.5

-0.5

3.9. Traço

x={1 2 3,

5 6,

4

2 4};

traco=trace(x);

print traco;

6

TRACO

10

3.10. Transposição

x={ 1.9 2

3,

40

5.2 6,

60

20

4.3};

transp1=t(x);

transp2=x`;

OperaçõesOperaçõesOperaçõesOperações BásicasBásicasBásicasBásicas

print transp1 transp2;

TRANSP1

TRANSP2

1.9

40

60

1.9

40

60

2

5.2

20

2

5.2

20

3

6

4.3

3

6

4.3

Note que há duas formas diferentes de transpor uma matriz, uma com o argumento pós- fixado e uma com o argumento pré-fixado. Evidentemente, ambas produzem o mesmo resultado.

3.11. Comparações entre Matrizes

O SAS/IML possui operadores que permitem realizar a comparação entre os elementos de duas matrizes, fornecendo como resultado uma nova matriz de uns e zeros, conforme a comparação seja verdadeira ou falsa, respectivamente. A sintaxe dos operadores é: matriz1 < matriz2, matriz1 <= matriz2, matriz1 > matriz2, matriz1 >= matriz2, matriz1 = matriz2, matriz1 ^= matriz2. Os dois últimos operadores permitem identificar matriz iguais, mas devemos sempre observar que isso pode ocorrer devido a erros de aproximação. Alguns exemplos:

a={1 7 3,

4 2 4};

b={0 8 2,

4 1 3};

menor= a<b; menorig= a<=b; maior= a>b; maiorig= a>=b; igual= a=b; diferent= a^=b; print menor menorig maior maiorig igual diferent;

MENOR

MENORIG

0

1

0

0

1

0

0

0

0

1

0

0

MAIOR

MAIORIG

1

0

1

1

0

1

0

1

1

1

1

1

IGUAL

DIFERENT

0

0

0

1

1

1

1

0

0

0

1

1

OperaçõesOperaçõesOperaçõesOperações BásicasBásicasBásicasBásicas

3.12. Concatenação de Matrizes e Vetores

A concatenação

excelente ferramenta para análise de dados em situações reais. Vejamos alguns exemplos:

pode

ser

feita

horizontalmente

ou

verticalmente,

fornecendo

uma

A={4 3,

-2 5};

b={10,

8};

C={7 -10,

4 13};

A_b=A||b; A_C=A//C; print A_b A_C;

 

A_B

A_C

4

3

10

4

3

-2

5

8

-2

5

 

7

-10

4

13

A matriz A e o vetor b foram concatenados horizontalmente usando o operador ||. Já as matrizes A e C foram concatenadas verticalmente usando //, obviamente observando se as dimensões são compatíveis.

3.13. Escalonamento de Matrizes

O SAS/IML possui duas funções para obtenção de formas escalonadas, HERMITE e

ECHELON, resultando matrizes na forma de Hermite e Echelon, respectivamente.

x={3

6

9,

1 2

5,

2 4 10};

h=hermite(x);

 

e=echelon(x);

print h e;

H

E

1

2

0

1

2

0

0

0

0

0

0

1

0

0

1

0

0

0

Note que, para essas matrizes, as formas escalonadas resultantes são diferentes, sendo a segunda delas a forma escalonada canônica.

OperaçõesOperaçõesOperaçõesOperações BásicasBásicasBásicasBásicas

3.14. Posto de Matrizes

As formas escalonadas permitem determinar o posto de matrizes:

A={4 2 2,

2 0,

2

2

0 2};

B={3 1 2,

1 4 1,

2 1 5};

C={1 2 3 4,

2 4 6 8};

Aesc=echelon(A); Besc=hermite(B); Cesc=echelon(C); print Aesc Besc Cesc;

AESC

BESC

1

0

1

1

0

0

0

1

-1

0

1

0

0

0

0

0

0

1

CESC

1

2

3

4

0

0

0

0

Verifica-se que o posto de A, B e C é 2, 3 e 1, respectivamente.

Embora o SAS/IML não possua uma função que forneça diretamente o posto de uma matriz (a função RANK fornece o rank dos elementos, e não da matriz, como desejado), isso pode ser conseguido com o auxílio de um programa auxiliar, apresentado a seguir. Ele bas

eia-se nos teoremas 55 (r[A]=r[A+A]) e 50 (A+A é simétrica e idempotente), lembrando ainda que para matrizes idempotentes o rank é igual ao traço. A função ROUND arredonda o valor encontrado, que é sujeito a pequenos erros de aproximação.

A={4 2 2,

2 0,

2

2

0 2};

B={3 1 2,

1 4 1,

2 1 5};

C={1 2 3 4,

2 4 6 8};

RANK_A=round(trace(ginv(A)*A));

RANK_B=round(trace(ginv(B)*B));

RANK_C=round(trace(ginv(C)*C));

InversaInversaInversaInversa dededede MatrizMatrizMatrizMatriz NãoNãoNãoNão SingularSingularSingularSingular

print RANK_A RANK_B RANK_C;

RANK_A

RANK_B

RANK_C

2

3

1

RANK_B RANK_C; RANK_A RANK_B RANK_C 2 3 1 4 Inversa de Matriz Não Singular Apresentaremos a

4 Inversa de Matriz Não Singular

Apresentaremos a seguir três formas diferentes de calcular a inversa de matriz não singular, sendo que a primeira delas (INV1) foi incluída apenas por razões didáticas, usando o algoritmo de Gauss.

B={3 1 2,

1 4 1,

2 1 5};

INV1=hermite(B||I(3));

INV2=inv(B);

INV3=B**(-1);

print INV1 INV2 INV3;

INV1

1

0

0

0.475

-0.075

-0.175

0

1

0

-0.075

0.275

-0.025

0

0

1

-0.175

-0.025

0.275

INV2

INV3

0.475

-0.075

-0.175

0.475

-0.075

-0.175

-0.075

0.275

-0.025

-0.075

0.275

-0.025

-0.175

-0.025

0.275

-0.175

-0.025

0.275

Aproveitaremos a matriz INV1, que contém a inversa de B à direita da identidade, para mostrarmos como selecionar submatrizes de uma dada matriz. É possível selecionar linhas, colunas ou até mesmo elementos de interesse. Para tanto, utilizam-se subscritos,que são operadores localizados dentros de colchetes, após o operando. O primeiro número refere-se a(s) linha(s) a ser(em) retirada(s) e o segundo a(s) coluna(s), sendo que eles devem ser separados por uma vírgula. Para selecionar um único elemento, como por exemplo da 3a linha e 4a coluna (lembre-se que INV1 tem dimensão 3 x 6):

B={3 1 2,

1 4 1,

InversaInversaInversaInversa dededede MatrizMatrizMatrizMatriz NãoNãoNãoNão SingularSingularSingularSingular

2 1 5};

INV1=hermite(B||I(3));

elem3_4=INV1[3,4];

print elem3_4;

ELEM3_4

-0.175

Para selecionar a linha 3 ou a coluna 4:

B={3 1 2,

1 4 1,

2 1 5};

INV1=hermite(B||I(3));

linha3=INV1[3,];

coluna4=INV1[,4];

print linha3 coluna4;

LINHA3

COLUNA4

0

0

1

-0.175

-0.025

0.275

0.475

 

-0.075

-0.175

Para selecionar uma submatriz, como por exemplo a inversa sem a parte referente à matriz identidade:

B={3 1 2,

1 4 1,

2 1 5};

INV1=hermite(B||I(3));

INVERSA=INV1[, {4 5 6}];

print INVERSA;

 

INVERSA

0.475

-0.075

-0.175

-0.075

0.275

-0.025

-0.175

-0.025

0.275

Note que é necessário utilizar chaves para correta especificação da sub-matriz.

DeterminantesDeterminantesDeterminantesDeterminantes

DeterminantesDeterminantesDeterminantesDeterminantes 5 Determinantes O SAS/IML calcula o determinante de matrizes

5 Determinantes

O SAS/IML calcula o determinante de matrizes quadradas de forma simples, através da

função DET, considerando o fato de que o determinante pode ser obtido através do produto dos autovalores da matriz em questão, que por sua vez são obtidos pela decomposição LU (matrizes triangulares). O resultado fornecido é uma matriz 1x1 (escalar) contendo o determinante.

proc iml; a={1 1 1,

1 2 4,

1 3 9};

determ=det(a);

print determ;

DETERM

2

Não há uma função específica para se obter matrizes adjuntas e dos cofatores de uma matriz de interesse.

adjuntas e dos cofatores de uma matriz de interesse. 6 Sistemas Consistentes de Equações Lineares O

6 Sistemas Consistentes de Equações Lineares

O SAS possui a função SOLVE para a solução de sistemas de equações lineares (consistentes

e determinados), que é muito eficiente em termos computacionais, devendo ser usado em situações práticas. Contudo, sempre com finalidades didáticas, serão apresentadas outras formas de resolver sistemas.

Para usar a função SOLVE para resolver o sistema Ax=b, pode-se proceder como apresentado a seguir.

A={4 3, -2 5}; b={10, 8}; x=solve(A,b); print x;

X

SistemasSistemasSistemasSistemas ConsistentesConsistentesConsistentesConsistentes dededede EquaçõesEquaçõesEquaçõesEquações LinearesLinearesLinearesLineares

1

2

As formas escalonadas apresentadas também podem ser usadas para solução de sistemas de equações lineares. Considerando o mesmo sistema com duas equações e duas incógnitas, escrito na forma matricial Ax=b, um programa para obter sua solução pode ser:

A={ 4 3, -2 5};

b={10,

8};

A_b=A||b;

SOL1=echelon(A_b);

SOL2=hermite(A_b);

print SOL1 SOL2;

O escalonamento forneceu a solução do sistema para x, com resultados 1 e 2.

SOL1

SOL2

1

0

1

1

0

1

0

1

2

0

1

2

Caso desejemos resolver o sistema usando o método de Kramer, podemos usar o seguinte programa:

reset print; A={1 1 2,

2 0 3,

1 1 0};

B={ 9,

11,

3};

A1=B || A[, {2 3}]; A2=A[,1] || B || A[,3]; A3=A[, {1 2}] || B; DET_A=det(A);

DET_A1=det(A1);

DET_A2=det(A2);

DET_A3=det(A3);

X1=DET_A1/DET_A;

X2=DET_A2/DET_A;

X3=DET_A3/DET_A;

SOLUCAO=X1//X2//X3;

Vale lembrar que não houve necessariamente a preocupação em elaborar programas mais sintéticos e eficientes. Nesse contexto, foram definidas as matrizes A, B, A1, A2 e A3, com

SistemasSistemasSistemasSistemas ConsistentesConsistentesConsistentesConsistentes dededede EquaçõesEquaçõesEquaçõesEquações LinearesLinearesLinearesLineares

seus respectivos determinantes. Em seguida, foi obtida a solução do sistema, concatenada no vetor SOLUCAO. O comando RESET PRINT solicita a visualização de todas as matrizes criadas, facilitando a visualização dos resultados, embora com excesso de informações. Para desativá-lo, deve-se usar RESET NOPRINT. A saída do programa acima é

A

3 rows

3 cols

(numeric)

1 1

2

2 0

3

1 1

0

B

3 rows

1 col

(numeric)

9

11

3

A1

3 rows

3 cols

(numeric)

9

1

2

11

0

3

3

1

0

A2

3 rows

3 cols

(numeric)

1

9

2

2

11

3

1

3

0

A3

3 rows

3 cols

(numeric)

1

1

9

2

0

11

1

1

3

DET_A

1 row

1 col

(numeric)

4

DET_A1

1 row

1 col

(numeric)

4

DET_A2

1 row

1 col

(numeric)

8

DET_A3

1 row

1 col

(numeric)

12

X1

1 row

1 col

(numeric)

1

X2

1 row

1 col

(numeric)

2

X3

1 row

1 col

(numeric)

3

SistemasSistemasSistemasSistemas ConsistentesConsistentesConsistentesConsistentes dededede EquaçõesEquaçõesEquaçõesEquações LinearesLinearesLinearesLineares

SOLUCAO

3 rows

1 col

(numeric)

1

2

3

Um programa mais sintético pode ser:

reset noprint;

A={1 1

B={ 9, 11, 3}; A1=B || A[, {2 3}]; A2=A[, 1] || B || A[, 3]; A3=A[, {1 2}] || B;

SOLUCAO=DET(A1)/DET(A)//DET(A2)/DET(A)//DET(A3)/DET(A);

print solucao;

2, 2 0

3,

1

1

0};

SOLUCAO

1

2

3

No caso de obter soluções para sistemas de equações lineares homogêneos do tipo Ax=(, sendo A de dimensão m x n, mn, é possível utilizar a função HOMOGEN, que retorna soluções como colunas ortonormais de uma matriz X com as propriedades Ax=( (P1) e X'X=I (P2). Para tanto, o posto de A deve ser r<n, ou seja, A deve ser de posto incompleto. A dimensão dessa matriz X é n x (n-r), e portanto deve ser dada especial atenção a matrizes mal-condicionadas, já que o correto posto de A pode não ser obtido em função de erros de aproximação.

A={4 2 2,

2 0,

2

2

0 2};

X=HOMOGEN(a);

P1=A*X;

P2=T(X)*X;

print X P1 P2;

X

P1

P2

-0.57735

2.22E-16

1

0.5773503 2.22E-16

0

0.5773503

Nesse caso, x é a solução não trivial, e P1 e P2 a verificação das propriedades da solução. Note que pequenos erros de aproximação podem ocorrer.

RaízesRaízesRaízesRaízes CaracterísticasCaracterísticasCaracterísticasCaracterísticas (autovalores)(autovalores)(autovalores)(autovalores)

Um outro fato que pode ser mencionado é que a dimensão da matriz com as soluções do sistema homogêneo podem ser usadas para calcular o posto da matriz A, já que não há uma função específica para tanto:

POSTO_A=NROW(X)-NCOL(X); print POSTO_A;

POSTO_A

2

tanto: POSTO_A=NROW(X)-NCOL(X); print POSTO_A; POSTO_A 2 7 Raízes Características (autovalores) Para obter os

7 Raízes Características (autovalores)

Para obter os autovalores ("eingenvalues") de matrizes quadradas simétricas, usa-se a função EIGVAL, que fornece um vetor com os autovalores ordenados em ordem decrescente.

A={3 1 1,

1 3 1,

1 1 3};

AUTOVAL=EIGVAL(A);

print AUTOVAL;

AUTOVAL

5

2

2

Caso necessitemos obter os autovalores a partir da equação característica, podemos usar a função POLYROOT, que encontra as raízes de um polinômio real. A sintaxe é POLYROOT(vetor), em que o vetor de dimensão 1 x n contém os coeficientes de um polinômio de grau n-1, sendo que eles devem estar em ordem decrescente, com relação as potências do polinômio. O resultado é uma matriz de dimensão (n-1) x 2, com as raízes do polinômio; a primeira coluna contém a parte real e a segunda, a parte imaginária (que deverá ser zero, no contexto desse curso). No exemplo em questão, a equação característica é -x3+9x2-24x+20=0, e assim

p={-1 9 -24 20}; raizes=POLYROOT(p);

RaízesRaízesRaízesRaízes CaracterísticasCaracterísticasCaracterísticasCaracterísticas (autovalores)(autovalores)(autovalores)(autovalores)

print raizes;

RAIZES

2.0000003

0

1.9999997

0

5

0

É interessante notar que as soluções estão sujeitas a erros de aproximação, em função do

algoritmo empregado. Um outro aspecto que deve ser lembrado diz respeito ao fato do SAS/

IML usar um algoritmo que não garante que todas as raízes do polinômio sejam encontradas; nesses casos, há uma mensagem para o usuário na janela LOG. Nas situações em que desejamos obter matrizes diagonais com as raízes características de uma dada matriz, combinamos a função DIAG, que cria matrizes diagonais, com a função EIGVAL.

M={ 2 -1 -1,

2 -1,

-1

-1 -1

2};

AUTOV=EIGVAL(M);

L=DIAG(AUTOV);

PRINT AUTOV L;

AUTOV

L

3

3

0

0

3

0

3

0

-9.11E-17

0

0 -9.11E-17

É fácil verificar que, exceto devido a erros de aproximação, M é positiva semi-definida.

Caso apliquemos o comando DIAG em uma matriz (e não num vetor, como no exemplo acima), teremos como resultado uma matriz formada pelos elementos da diagonal dessa matriz, sendo os demais substituídos por zero.

Para facilitar a visualização, poderíamos ainda usar a opção FUZZ, associada ao comando RESET, de modo que os números muito pequenos (por volta de 1E-12) sejam impressos como zero.

reset fuzz; PRINT AUTOV L;

 

AUTOV

L

3

3

0

0

3

0

3

0

VetoresVetoresVetoresVetores CaracterísticosCaracterísticosCaracterísticosCaracterísticos (autovetores)(autovetores)(autovetores)(autovetores)

0

0

0

0

Para voltarmos ao default, dentro da mesma seção do IML, devemos usar o comando RESET NOFUZZ.

mesma seção do IML, devemos usar o comando RESET NOFUZZ. 8 Vetores Característicos (autovetores) A obtenção

8 Vetores Característicos (autovetores)

A obtenção dos autovetores ("eingenvectors") de matrizes quadradas simétricas pode ser

feita pelo uso da função EIGVEC, que cria uma matriz cujas colunas são autovetores

ortonormais.

A={3 1 1,

1 3 1,

1 1 3};

AUTOVEC=EIGVEC(A);

print AUTOVEC;

 

AUTOVEC

0.5773503

-0.408248

0.7071068

0.5773503

-0.408248

-0.707107

0.5773503

0.8164966

0

É fácil verificar que esses vetores são ortogonais entre si, pois o produto entre autovalores

diferentes é 0, apresentando como resultado de seu produto consigo mesmo o valor 1 (norma 1). Em outras palavras, o produto entre a transposta da matriz com os autovalores e ela própria é a identidade:

RESET FUZZ; AUTOVEC=EIGVEC(A); ORTONORM=AUTOVEC`*AUTOVEC; print ORTONORM;

ORTONORM

1

0

0

0

1

0

0

0

1

Em situações práticas, podemos obter os autovalores e autovetores diretamente, com o uso da sub-rotina EIGEN, acionada pelo comando CALL, que invoca determinadas estruturas

FormasFormasFormasFormas EquivalentesEquivalentesEquivalentesEquivalentes

(operações) pré-armazenadas. O primeiro termo dentro dos parênteses especifica o nome da matriz que conterá os autovalores; o segundo, da matriz que conterá os autovetores; oterceiro indica sobre qual matriz o comando será aplicado.

CALL EIGEN(AUTOVAL,AUTOVET,A); print AUTOVAL AUTOVET;

AUTOVAL

AUTOVET

5

0.5773503 -0.408248 0.7071068

2

0.5773503 -0.408248 -0.707107

2

0.5773503 0.8164966

0

-0.408248 -0.707107 2 0.5773503 0.8164966 0 9 Formas Equivalentes As matrizes A e B são equivalentes

9 Formas Equivalentes

As matrizes A e B são equivalentes se existem M e N não singulares tais que MAN=B. B é dita forma normal de A. O SAS/IML fornece a forma normal de Hermite da matriz A, usando função já vista anteriormente. Para matrizes quadradas, essa forma é triangular superior e idempotente. Se A for não singular, o resultado será uma matriz identidade.

A={4 2 2,

2 2 0,

2 0 2};

B=hermite(A);

print B;

B

1

0

1

0

1

-1

0

0

0

É possível também obter a forma normal de Echelon que, nesse caso, coincide com a forma normal de Hermite:

B=echelon(A);

print B;

B

FormasFormasFormasFormas EquivalentesEquivalentesEquivalentesEquivalentes

1

0

1

0

1

-1

0

0

0

Se a matriz em questão for quadrada, as formas normais de Hermite e Echelon podem ser obtidas uma a partir da outra, apenas rearranjando as linhas de zeros. A forma de Echelon sempre fornece uma forma escalonada canônica.

Para a obtenção de uma matriz D diagonal congruente (e, portanto, equivalente) à matriz A real e simétrica considerada, tal que TAT '=D, utiliza-se a sub-rotina EIGEN, pelo comando CALL EIGEN(D, T, A), já descrito anteriormente. Para tanto, utilizam-se as seguintes propriedades das matrizes obtidas com esse comando: T' = T-1 (ortogonal) e A=T*diag(D)*T', ou seja, diag(D) é uma matriz diagonal congruente à matriz A.

A={4 2 2,

2 0,

2

2

0 2};

CALL EIGEN (D,T,A); CONG=DIAG(D);

A2=T*DIAG(D)*T`;

reset FUZZ; print A A2;

 

A

A2

4

2

2

4

2

2

2

2

0

2

2

0

2

0

2

2

0

2

Dessas propriedades, conseguimos também verificar que diag(D)= T'*A*T, em que diag(D)

é uma matriz diagonal que exibe as raízes características de A, e T é uma matriz ortogonal cujas linhas são vetores característicos normalizados associados as raízes características de

A.

L1=DIAG(D);

L2=T`*A*T;

print L1 L2;

 

L1

L2

6

0

0

6

0

0

0

2

0

0

2

0

0

0

0

0

0

0

Nesse caso, A e diag(D) são também similares.

FatoraçãoFatoraçãoFatoraçãoFatoração

FatoraçãoFatoraçãoFatoraçãoFatoração 10 Fatoração O SAS/IML não realiza diretamente fatorações do tipo

10

Fatoração

O SAS/IML não realiza diretamente fatorações do tipo A=RR', fatorações de posto completo do tipo A=BC e operações de diagonalização simultânea. No primeiro caso, é possível a obtenção de fatorações do tipo raiz quadrada de outra forma, apresentada abaixo.

Uma vez que o principal interesse na fatoração de posto completo é para a obtenção da inversa generalizada de Moore-Penrose, a ausência da fatoração não representa empecilho, uma vez que essa inversa generalizada é calculada pelo SAS (itens seguintes). No manual, temos diversas outras decomposições que podem interessar ao leitor.

Fatorações do tipo A=U'U são obtidas com a função ROOT, que retorna uma matriz triangular superior U que satisfaz a igualdade, sendo que a matriz A deve ser simétrica e positiva definida. Essa decomposição é conhecida como decomposição de Cholesky, e a matriz U é dita raiz quadrada de A.

U=ROOT(A);

A1=U`*U;

print U A1;

 

U

A1

2

1

1

4

2

2

0

1

-1

2

2

0

0

0

0

2

0

2

Vale ressaltar que alguns autores denominam a fatoração A=RR' como raiz quadrada, e não A=U'U, como o SAS considera. É interessante notar que essa fatoração também é do tipo triangular (A=LU), uma vez que U' é triangular inferior e U é triangular superior.

Para realizar decomposição por valores singulares do tipo X=USV´, o SAS/IML possui a sub- rotina SVD, acessada pelo comando CALL. Sua sintaxe é CALL SVD(U, S, V, X), em que X representa a matriz a ser decomposta, U, S e V, o nome das matrizes a serem criadas com o resultado da decomposição, de forma que X=U*diag(S)*V´ e S contenha os valores singulares de A. Note que o algoritmo apresentado no texto das aulas teóricas produz matrizes diferentes, mostrando que a decomposição não é única.

reset print; X={1 1 0,

1 1 0,

1 0 1,

1 0 1};

call svd(U,S,V,X);

X1=U*diag(S)*V`;

InversasInversasInversasInversas GeneralizadasGeneralizadasGeneralizadasGeneralizadas

X

4 rows

3 cols

(numeric)

1 1

0

1 1

0

1 0

1

1 0

1

U

4 rows

3 cols

(numeric)

0.5

0.5 0.7071068

0.5

0.5 -0.707107

0.5

-0.5

0

0.5

-0.5

0

S

3 rows

1 col

(numeric)

2.4494897

 

1.4142136

 

0

V

3 rows

3 cols

(numeric)

0.8164966

0 -0.57735

0.4082483

0.7071068 0.5773503

0.4082483

-0.707107 0.5773503

X1

4 rows

3 cols

(numeric)

1

1

0

1 1

0

1 0

1

1 0

1

1 1 0 1 1 0 1 0 1 1 0 1 11 Inversas Generalizadas É

11 Inversas Generalizadas

É possível calcular a inversa generalizada de Moore-Penrose usando o SAS/IML, com o comando GINV(X), em que X é a matriz a ser invertida. A inversa obtida satisfaz as quatro condições da inversa, conforme apresentado abaixo.

X={1 1 0,

1 1 0,

1 0 1,

1 0 1};

MP1=ginv(X);

P1=MP1*X*MP1;

P2=X*MP1*X;

P3a=X*MP1; P3b=t(X*MP1); P4a=MP1*X; P4b=t(MP1*X); print MP1;

InversasInversasInversasInversas GeneralizadasGeneralizadasGeneralizadasGeneralizadas

print P1 P2 P3a P3b P4a P4b;

MP1

0.1666667

0.1666667 0.1666667 0.1666667

0.3333333

0.3333333 -0.166667 -0.166667

-0.166667 -0.166667 0.3333333 0.3333333

P1

P2

0.1666667

0.1666667 0.1666667 0.1666667

1

1

0

0.3333333

0.3333333 -0.166667 -0.166667

1

1

0

-0.166667 -0.166667 0.3333333 0.3333333

1

0

1

 

1

0

1

P3A

P3B

0.5

0.5

0

0

0.5

0.5

0

0

0.5

0.5

0

0

0.5

0.5

0

0

0

0

0.5

0.5

0

0

0.5

0.5

0

0

0.5

0.5

0

0

0.5

0.5

P4A

P4B

0.6666667

0.3333333 0.3333333 0.6666667 0.3333333 0.3333333

0.3333333

0.6666667 -0.333333 0.3333333 0.6666667 -0.333333

0.3333333

-0.333333 0.6666667 0.3333333 -0.333333 0.6666667

As inversas generalizadas reflexivas g2 para matrizes de delineamento podem ser obtidas

com a função SWEEP. Tomando o modelo linear de Gauss-Markov , podemos

obter o sistema

y

= XB + e

X'X X'y

y'x y'y

e, usando o operador SWEEP sobre esse sistema, calcular uma matriz

( X'X ) g2

y'X X'X )

(

g2

( X'X ) g2 X'y

y' I X X'X )

(

(

g2

X ' ) y

A partição superior esquerda dessa matriz contêm a inversa g2 de X'X, a partição superior

direita as soluções para B e apartição inferior direita a soma de quadrados do resíduo. Esse

é o procedimento usado pelo PROC GLM do SAS para realizar análises de variância. Um exemplo é apresentado abaixo, sendo que o segundo argumento da função SWEEP é um vetor com índices variando de 1 até o posto de X.

reset print; X={1 1 0,

1 1 0,

1 0 1,

1 0 1};

y={1,

InversasInversasInversasInversas GeneralizadasGeneralizadasGeneralizadasGeneralizadas

2,

4,

3};

A=(t(X)*X||t(X)*y)//(t(y)*X||t(y)*y);

t=1:ncol(X);

G=sweep(A,t);

reset noprint;

X

4 rows

3 cols

(numeric)

1

1

0

1

1

0

1

0

1

1

0

1

Y

4 rows

1 col

(numeric)

1

2

4

3

A

4 rows

4 cols

(numeric)

4

2

2

10

2

2

0

3

2

0

2

7

10

3

7

30

T

1 row

3 cols

(numeric)

1

2

3

G

4 rows

4 cols

(numeric)

0.5

-0.5

 

0

3.5

-0.5

 

1

0

-2

 

0

0

0

0

-3.5

 

2

0

1

Leitores já familiarizados com o PROC GLM podem verificar as afirmativas acima com o seguinte programa:

data;

input trat Y@@;

datalines;

1

1

1

2 2 4 2

3

;

InversasInversasInversasInversas GeneralizadasGeneralizadasGeneralizadasGeneralizadas

proc glm; class trat; model Y=trat/inverse; run;

The GLM Procedure

Class Level Information

Class

Levels

Values

trat

2

1

2

Number of observations

4

X'X Generalized Inverse (g2)

Intercept

 

trat 1

trat 2

Y

Intercept

0.5

-0.5

0

3.5

trat 1

-0.5

1

0

-2

trat 2

0

0

0

0

Y

3.5

-2

0

1

Dependent Variable: Y

 

Sum of

Source

DF

Squares

Mean Square

F Value

Pr > F

Model

1

4.00000000

4.00000000

8.00

0.1056

Error

2

1.00000000

0.50000000

Corrected Total 3

5.00000000

R-Square

Coeff Var

Root MSE

Y Mean

0.800000

28.28427

0.707107

2.500000

Source

DF

Type I SS

Mean Square

F Value

Pr > F

trat

1

4.00000000

4.00000000

8.00

0.1056

Source

DF

Type III SS

Mean Square

F Value

Pr > F

trat

1

4.00000000

4.00000000

8.00

0.1056