FEUP Licenciatura em Eng. Civil Computação 10 4 4.1 Arrays Dada uma matriz A(n × n) e um vector v(n × 1) de números inteiros escreva instruções para: Matlab (a) vericar se todos os elementos de v são positivos. (b) calcular o produto dos elementos pares de v . (c) determinar a soma do produto de cada elemento da diagonal principal da matriz A pelo elemento correspondente de v . (d) determinar o somatório dos elementos das duas primeiras linhas e da última linha. Resolução: A=input('matriz quadrada nxn= '); v=input('vector com nx1= '); %a) a=all(v>0) %b) b=prod(v(mod(v,2)==0)) %c) c=sum(diag(A).*v) % diag dá um vector coluna %d) d1=sum(A(1,:)+A(2,:)+A(end,:)) % ou melhor d2=sum(sum(A([1,2,end],:))) 4.2 Repita os exercícios 1.1 e 1.2, destas folhas de exercícios, usando instruções Resolução: %1.1 disp('1.1') v=input('vector= '); %a) disp('a)') vv=v; vv(mod(vv,2)==1)=0 %b) disp('b)') vimpar=v(mod(v,2)==1) %c) disp('c)') p=prod(v(1:2:end)) %d) já têm de saber if disp('d)') Matlab. 4. Arrays 11 x=input('Qual o valor? '); vv=find(v==x); if isempty(vv) disp(['não há elementos iguais a ', num2str(x)]) else disp(['O índice do elemento é ',int2str(vv(1))]) end %1.2 disp('1.2') A=input('matriz = '); %a) disp('a)') A(1,:)=sum(A([1,2],:)) %b) disp('b)') vl=any(mod(A(:,3),10)==5) %c) disp('c)') p=prod(A(end,:)) %d) disp('d)') x=input('escalar? '); MS=A+x %e) disp('e)') s=sum(diag(A)) % diag dá os elementos em que os índices são iguais %f) disp('f)') A=A([end 2:end-1 1],:) 4.3 Dada uma matriz A escreva instruções (a) (b) (c) (d) Matlab para: determinar a matriz C : Cij = Aij ∗ j . determinar quais os índices dos elementos de A maiores do que 3. eliminar as colunas ímpares de A. eliminar as linhas de A com elementos ímpares. Resolução: A=input('matriz = '); %a) [n, m]=size(A); p=1:m; 12 FEUP Licenciatura em Eng. Civil Computação aux=p(ones(n,1),:); % tambem pode ser p(ones(1,n),:) C=A.*aux % uma alternativa as duas ultimas linhas. Acho-a preferivel pois nao % tem que usar a matriz aux com n*m elementos %for i=1:n % C(i,:)=A(i,:).*p %end %b) % se so quiser a ordem no vector coluna com todos os elementos da matriz k=find(A>3) % ou se quiser o indice de linha e o indice de coluna [i,j]=find(A>3); disp([i j]) %c) A(:,1:2:m)=[] % se nao quiser alterar A fazer B=A(:,2:2:m) %d) l=any(mod(A,2)~=0,2); A(l,:)=[] 5. Instruções se salto, ciclos e repetição 5 5.1 13 Instruções se salto, ciclos e repetição Matlab e escreva um possível enunciado Explique o que fazem os seguinte programa para o problema que cada programa resolve. (a) n=input('dimensao da matriz quadrada= '); A=fix(10*rand(n)) for i=1:n t=A(i,i); A(i,i)=A(i,n+1-i); A(i,n+1-i)=t; end disp(A) Resolução: Escreva um programa que proceda à troca entre os elementos da diagonal principal e os da secundária, para uma matriz quadrada inteira gerada aleatoriamente entre 0 e 10. Explicação: No início do programa é pedida a dimensão da matriz que é armazenada em n. É então gerada, aleatoriamente rand(n), uma matriz quadrada de dimensão n × n com valores entre 0 e 1. Ao multiplicar essa matriz por 10 e ao considerar a parte inteira fix(... vai-se obter uma matriz com números inteiros entre 0 e 10 ( a probabilidade de encontrar o 10 é praticamente nula pois só é obtida quando na matriz aleatória se tiver exactamente 1). Depois é utilizado um ciclo for para percorrer todos os elementos i=1:n da diagonal principal A(i,i) e da diagonal secundária A(i,n+1-i). Com A(i,i) temos a diagonal principal porque o índice da linha é igual ao índice da coluna e, com A(i,n+1-i) temos a diagonal secundária porque a soma dos índices dos elementos da diagonal secundária é n + 1 = i + (n + 1 − i). As instruções dentro do ciclo permitem, com a ajuda da variável auxiliar t, trocar os conteúdos dos elementos das duas diagonais que estão na mesma linha pois, em ambos, o índice da linha é igual a i. No nal a matriz resultante é escrita. Enunciado: (b) M=input('matriz= '); [nl nc]=size(M); if nl~=nc disp['M tem que ser quadrada') else j=nc-1; pr=1; for i=2:2:nl pr=pr*M(i,i)*M(j,i); j=j-2; FEUP Licenciatura em Eng. Civil Computação 14 end end disp(['produto= ',num2str(pr)]) Resolução: Escreva um programa que, dada uma matriz quadrada, calcule o produto dos elementos das diagonais principal e secundária pertencentes a colunas pares da matriz. Se a matriz não for quadrada deve ser escrita uma mensagem de erro e o programa pára. Explicação: No início do programa é pedida a matriz que é armazenada em M e em nl e nc ([nl nc]=size(M)) são armazenados respectivamente o número de linhas e colunas (a sua dimensão). Com o if é analisado se nl e nc são diferentes. Se forem, é escrita a mensagem M tem que ser quadrada e, como não tem mais instruções depois de end, o programa termina. Caso contrário vai ser denida uma variável j = nc − 1 (nc = nl) que vai ser índice de linha em M(j,i). Como o primeiro valor que i toma é 2, este elemento vai pertencer à diagonal secundária de M pois (nc − 1) + 2 = nc + 1 = nl + 1 e os elementos da diagonal secundária são caracterizados pela soma dos índices ser igual a nl + 1. Os restantes elementos M(j,i) percorridos pelo ciclo for vão ter o índice da coluna i incrementado de 2 unidades e o índice j decrementado também de 2 unidades, logo a sua soma continua a ser nl+1 e o elemento vai percorrer os elementos da diagonal secundária pertencentes a colunas pares. Como M(i,i) percorre os elementos da diagonal principal (índice da linha igual ao índice da coluna) com o i a variar de 2 até nl por incrementos de 2 unidades, estes elementos só pertencem às colunas pares. Com pr=pr*M(i,i)*M(j,i); é efectuado recursivamente o produto de todos esses elementos, armazenando o resultado em pr. Para o resultado dessa recursão ser correcto, antes do ciclo começar com pr=1 é inicializada a variável de recorrência com o elemento neutro do produto. No m do ciclo, e quando nl = nc é escrito o valor desse produto usando um disp. Enunciado: 5.2 Escreva um programa em Matlab que: (a) peça ao utilizador uma matriz M . (b) peça ao utilizador um vector coluna v com tantos elementos quantas as linhas de M , abortando se não for esse o caso. (c) calcule o produto escalar do vector v com a penúltima coluna da matriz M . (d) escreva a sub-matriz de M de dimensão 2 × 2 , cujo termo do canto superior esquerdo é o termo (2,1) de M . (e) escreva V ou F conforme o vector v seja igual a uma das duas primeiras colunas de M . 5. Instruções se salto, ciclos e repetição 15 Resolução: M=input('matriz nxm = '); v=input('vector nx1 = '); [nl nc]=size(M); [nlv ncv]=size(M); if nl~=nlv disp(' o vector nao tem a dimensao pretendida ') return else produto_escalar=v'* M(:,end-1) submatriz=M(2:3,1:2) if all(v==M(:,1))|| all(v==M(:,2)) disp('V') else disp('F') end end 5.3 Matlab Escreva programas para comparar a execução vectorial do com a execução por ciclos ... Use as funções tic e toc ou cputime para controlar os tempos de execução. (a) Some todos os elementos de uma matriz quadrada gerada aleatóriamente. Para não ter que trabalhar com matrizes muito grandes, repita o processo várias vezes com um ciclo. Resolução: % n dimensao da matriz % quantas vezes o calculo vai ser repetido n=input('dim matriz '); m=input('dim ciclo '); a=rand(n); % usando a funçao sum (elementos num vector) t1=cputime; %ou tic; for i=1:m s2=sum(a(:)); end t3=cputime-t1 %ou t3=toc % usando so um ciclo (elementos num vector) t2=cputime; %ou tic; for k=1:m s3=0; FEUP Licenciatura em Eng. Civil Computação 16 for i=1:n*n s3=s3+a(i); end end t4=cputime-t2 %ou t4=toc % usando dois ciclos (elementos numa matriz) t5=cputime; %ou tic; for k=1:m s3=0; for i=1:n for j=1:n s3=s3+a(i,j); end end end t6=cputime-t5 %ou t6=toc (b) Some os elementos da diagonal principal de uma matriz quadrada gerada aleatóriamente. Resolução: % n dimensao da matriz % quantas vezes o calculo vai ser repetido n=input('dim matriz '); m=input('dim ciclo '); a=rand(n); %controla o tempo de execuçao do ciclo t=cputime; %ou tic for i=1:m end t1=cputime-t %ou t1=toc %soma vectorial t=cputime; %ou tic for i=1:m s=sum(diag(a)); end t2=cputime-t %ou t2=toc % soma com ciclos t=cputime; %ou tic for k=1:m ss=0; for i=1:n ss=ss+a(i,i); end end 5. Instruções se salto, ciclos e repetição t3=cputime-t 17 %ou t2=toc (c) Some os elementos da diagonal secundária de uma matriz quadrada gerada aleatóriamente. Resolução: % n dimensao da matriz % quantas vezes o calculo vai ser repetido n=input('dim matriz '); m=input('dim ciclo '); a=rand(n); %soma vectorial t=cputime; %ou tic for i=1:m s=sum(diag(fliplr(a))); end t1=cputime-t %ou t1=toc % soma com ciclos t=cputime; %ou tic for k=1:m ss=0; for i=1:n ss=ss+a(i,n+1-i); end end t2=cputime-t %ou t2=toc % escrita dos valores calculados disp([' soma vectorial ',s]); disp([' soma com for ',ss]); (d) Resolva o exercício 5.18 a) de Exercícios de Computação (2003-2004) usando o termo geral da sucessão com o cálculo vectorial e, usando uma fórmula de recorrência, para denir o termo da sucessão, com um ciclo. Resolução: % vai repetir o calculo, soma de 10 parcelas, n vezes x=input('x= '); n=input('quantos ciclos? '); N=10; % calculo vectorial com termos gerais tic for k=1:n i=0:N-1; fact=cumprod(1:2*N-1); seno=sum( (-1).^i.*x.^(2*i+1)./fact(1:2:2*N-1)); 18 FEUP Licenciatura em Eng. Civil Computação coseno=sum((-1).^i.*x.^(2*i)./[1 fact(2:2:2*N-1)]); end t=toc disp([seno coseno seno^2+coseno^2]); % calculo com ciclos e termos definidos por recorrencia tic for k=1:n seno=x; coseno=1; uis=x; uic=1; for i=1:N-1; uis=-uis*x^2/((2*i+1)*2*i); uic=-uic*x^2/(2*i*(2*i-1)); seno=seno+uis; coseno=coseno+uic; end end t2=toc disp([seno coseno seno^2+coseno^2]);