Anda di halaman 1dari 10

!

******************************************************
! Funcao teorica.
!******************************************************

Real Function Pol(x,ord,coef)


Implicit none
Integer::i,ord
Real:: x,coef(0:ord)

Do i=0,ord
Pol=Pol+coef(i)*x**i
End Do
End Function

!******************************************************
! Aplicacao do metodo dos minimos quadrados.
!******************************************************

Subroutine min_quadrad (x, y,nmax,ord,m,b,somx,somxy)


Implicit None
Integer::i, j,k,ord,nmax
Real::x(nmax), y(nmax), somx(0:20), somxy(0:10), m(10,10),b(11)

!Calculo dos somatorios


Do i=0,ord+ord
somx(i)=0.0
Do j=1,nmax
somx(i)=somx(i)+x(j)**i
End Do
End Do
Do i=0,ord
somxy(i)=0
Do j=1,nmax
somxy(i)=y(j)*x(j)**i
End Do
End Do
!construcao da matriz m.
Do i=1,ord+1
k=1
Do j=i-1,i+ord-1

m(i,k)=somx(j)
k=k+1
End Do
End Do

!construcao da matriz b.
Do i=1,ord+1
b(i)=somxy(i-1)
End Do
End Subroutine

!****************************************************
! Transformacao da matriz m em matriz LU
!****************************************************

Subroutine LDU (n, M, mmax, trocas)


Implicit None
Integer::i, j, k, l, n, mmax, trocas(n), iM, trocax
Real::M(mmax,n), Maior, Mx

!Posicao inicial das linhas da matriz


Do i=1,n
trocas(i)=i
End Do

!transformacao LUD
Do j=1,n-1
Maior=M(j,j); iM=j
Do i=j+1,n
If(ABS(M(i,j)) > ABS(Maior))then
Maior=M(i,j)
iM=i
End If
If(ABS(Maior) < 1.0E-05)Then
Write(*,*)'Matriz mal&
& condicionada, pode conduzir a solucao de reduzido&
& significado!'
Return
End If
End Do

!troca de linhas se necessario


If(iM /= j) Then

Do k=1, n
Mx=M(iM,k)
M(iM,k)=M(j,k)
M(j,k)=Mx
End Do
!Registo das trocas de linhas
trocax=trocas(iM)
trocas(iM)=trocas(j)
trocas(j)=trocax
End If

!eliminacao dos elementos da coluna


Do k=j+1,n
If(M(k,j) /= 0.0)Then
M(k,j)=M(k,j)/M(j,j)
Do l=j+1,n
M(k,l)=M(k,l)-M(k,j)*M(j,l)
End do
End If
End Do
End Do
If(ABS(M(n,n)) < 1.0E-5)Then
Write(*,*)'Matriz mal condicionada,pode&
& conduzir a solucao de reduzido significado!'
Return
End If
End Subroutine

!********************************************************
! Resolucao do sistema de matrizes
!********************************************************

Subroutine Solve(M,n,mmax,trocas,B)
Real:: M(mmax,n), B(n), T(10), soma
Integer:: n, mmax,trocas(n),i,j

!troca das linhas de B, guarda em T.


Do i=1,n
T(i)=B(trocas(i))
End Do

! resolve usando sobst. progressiva Ly=B


Do i=2,n
soma=T(i)
Do j=1,i-1
soma=soma-M(i,j)*T(j)
End Do
T(i)=soma
End Do

! resolve usando subst. regressiva Ux=y


B(n)=T(n)/M(n,n)
Do i=n-1,1,-1
soma=T(i)
Do j=i+1,n
soma=soma-M(i,j)*B(j)
End Do
B(i)=soma/M(i,i)
End Do
End Subroutine
Subroutine comparar(ord, n, b, coef, dif, difmed)
Implicit None
Integer:: i, ord ,n
Real:: b(n), coef(0:ord), dif(0:ord) ,difmed
difmed=0.0
Do i=1,n
dif(i-1)=ABS((b(i))-(coef(i-1)))
Write(*,*)'a(',i-1,')modelo=',b(i),' a(',i-1,')teorico=',coef(i-1),' Diferenca entre
ambos=',dif(i-1)
difmed=difmed+dif(i-1)
End Do
Write(*,*)'Media das diferencas entre ambos coeficientes=',difmed
End Subroutine

!******************************************************************
! Programa principal
!******************************************************************

Program main
Implicit None
Real::x(50),y(50),xnt,ymx,ytx,Sr(50),Srtot,Erro_padrao,&
&somy2,Coef_corr
Real::Pol,m(10,10),somx(0:20),somxy(0:10),b(11),coef(0:10),&
&dif(0:10),difmed
Integer::i,j,n,nmax,ord,trocas(10) ,p ,q
Character::opcao,opcao2, detval, calc
Integer,Parameter::mmax=10

!menu inicial

3 Write(*,100)
pause

!menu principal
100 FORMAT (5(/),T10,65('#')/T10,'#',T34,'MENU PRINCIPAL',T74,'#'/T10,&
&65('#')/T10,'#',T74,'#'/T10,'#',T74,'#'/T10,'#',T14,'Prima:'&
&,T34,'Para:',T74,'#'/T10,'#',T14,6('-'),T34,29('-'),T74,'#'/T10,&
&'#',T16,'1',T34,'Iniciar o Programa',T74,'#'/T10,'#',T74,'#'/&
&T10,'#',T16,'0',T34,'O que faz este
Programa?',T74,'#'/T10,'#',T74,&
&'#'/T10,'#',T16,'9',T34,'Sair do programa',T74,'#'/T10,'#',T74,&
&'#'/T10,'#',T74,'#'/T10,65('#'),4(/))

read(*,*)p

if(p==1)then
goto 1
else if(p==0)then
goto 2
else if(p==9)then
goto 50
else
goto 4
end if

2
Write(*,*)'**************************************************************
*****************'
Write(*,*)'* Bem vindo! Este programa realiza uma&
& comparacao entre os ** valores dos coeficintes de uma equacao&
& teorica e os valores dos mesmos ** coeficientes obtidos pelo&
& metodo dos minimos quadrados a partir de um ** conjunto de pontos&
& experimentais.Permite ainda o calculo dos valores da ** funcao&
& para pontos desconhecidos, quer por via teorica quer pelo&
& polinomio ** resultante da regressao polinomial! *'

Write(*,*)'**************************************************************
*****************'

pause

goto 3

!Opcao de escolha da origem dos dados.


1 write(*,104)
!introduza nome do ficheiro
104 FORMAT (10(/),T15,50('*')/T15,'*',T64,'*',/T15,'*',T19,'Se optar por fazer a
leitura&
& a partir de um *',/T15,'*',T64,'*',/T15,'*',T19,'&
& ficheiro que contem os
dados',T64,'*',/,T15,'*',T64,'*'/T15,'*',T25,'na forma &
& dados.txt, prima f',T64,'*'/T15,'*',T64,'*',/T15,50('*'),10(/))

Read(*,*)opcao
!le os dados, n de pontos e valores de x e y, do ficheiro
If(opcao=='f')Then
Open(15,File='dados.txt',Status='unknown')
Read(15,*)nmax,ord
Do i=1,nmax
Read(15,*)x(i),y(i)
End Do
Read(15,*)(coef(i),i=0,ord)
Else
!le dados do ecran
10 Write(*,1000)' Quantos pontos possui?'
Read(*,*)nmax
If(nmax <= 0 .or. nmax >50)Then
Write(*,1000)' O valor e invalido!'
Goto 10
End If
Write(*,1000)' Introduza os os valores de x dos pontos!'
Read(*,*)(x(i),i=1,nmax)
Write(*,1000)' Introduza os valores de y correspondentes!'
Read(*,*)(y(i),i=1,nmax)
20 Write(*,*)' Qual o grau do polinomio que deseja calcular&
&(devera ser do mesmo grau que a eq. teorica)?'
Read(*,*)ord
If(ord < 0 .or. ord > 9)Then
Write(*,*)' O valor e invalido!'
Goto 20
End If
End If

1000 Format(T5,/,a)

!Escolha da origem dos resultados do run.


Write(*,*)' Deseja enviar os resultados para um ficheiro&
& (clique f) ou visualizar apenas no ecran (outra tecla qq)?'
Read(*,*)opcao2
If(opcao2=='f')Then
Open(30,File='resultados.txt',Status='Unknown')

End If

!Chamada das subrotinas


Call min_quadrad(x,y,nmax,ord,m,b,somx,somxy)
!n=ord+1 =>numero de equacoes
n=ord+1
!escrita da matriz antes de ser modificada.
Write(*,*)'Matriz m:'
Do i=1,n
If(opcao2=='f')Then
Write(30,*)(m(i,j),j=1,n)
End If
Write(*,*)(m(i,j),j=1,n)
End Do
Call LDU(n,m,mmax,trocas)
!escrita da matriz apos ser transformada em LU.
Do i=1,n
If(opcao2=='f')Then
Write(30,*)(m(i,j),j=1,n)
End If
Write(*,*)(m(i,j),j=1,n)
End Do
!Escrita do vector com as trocas de linhas ocorridas
Write(*,*)'Vector c/ as trocas de linhas'&
&,(trocas(i),i=1,n)
Call Solve(m,n,mmax,trocas,b)
!Escrita do vector com o valor dos coeficientes resultantes da
!aplicao do metodo.
If(opcao2=='f')Then
Write(30,*)' Vector dos coeficientes',(b(i),i=1,n)
End If
Write(*,*)' Vector dos coeficientes',(b(i),i=1,n)

!Quantificacao de erros
Do i=1,nmax
Sr(i)=0.0
Do j=0,ord
Sr=Sr+b(j)*x(i)**j
End Do
Sr(i)=(Sr(i)-y(i))**2
End Do
Srtot=0.0
Do i=1,nmax
Srtot=Srtot+Sr(i)
End Do

!Calculo do erro padrao


Erro_Padrao=SQRT(Srtot/(nmax-2))
If(opcao2=='f')Then
Write(30,*)' Erro padrao=', Erro_Padrao
End If
Write(*,*)' Erro padrao=', Erro_Padrao

!Calculo do coeficiente de correlacao


!Calculo do somatorio de y^2
Do i=1,nmax
somy2=somy2+y(i)*y(i)
End Do
Coef_corr=(somx(0)*somxy(1)-somx(1)*somxy(0))/&
&(SQRT(somx(0)*somx(2)-somx(1)**2)*&
&SQRT(somx(0)*somy2-somxy(0)**2))
If(opcao2=='f')Then
Write(30,*)' O Coeficiente de correlacao e =', Coef_corr
End If
Write(*,*)' Coeficiente de correlacao e =', Coef_corr

!comparacao dos valores dos coeficientes


If(opcao /= 'f')Then
Write(*,*)' Escreva o valor de todos os coeficientes&
& da equacao teorica(de 0 ate',ord,')?'
Read(*,*)(coef(i),i=0,ord)
End If
If(opcao2=='f')Then
Write(30,*)' Diferencas entre os coeficientes das equacoes&
& teorica e polinomio resultante!'
End If
Write(*,*)' Diferencas entre os coeficientes das equacoes&
& teorica e polinomio resultante!'
!---------
difmed=0.0
Do i=1,n
dif(i-1)=ABS(b(i)-coef(i-1))
If(opcao2=='f')Then
Write(30,*)'a(',i-1,')modelo=',b(i),'a(',i-1,')teorico=',&
&coef(i-1),' Diferenca entre ambos=',dif(i-1)
End If
Write(*,*)'a(',i-1,')modelo=',b(i),' a(',i-1,')teorico=',&
&coef(i-1),' Diferenca entre ambos=',dif(i-1)
difmed=difmed+dif(i-1)
End Do
If(opcao2=='f')Then
Write(30,*)' Media das diferencas entre ambos coeficientes='&
&,difmed/n
End If
Write(*,*)' Media das diferencas entre ambos coeficientes='&
&,difmed/n
!----------------

!opcao de determinacao de valores da funcao para pontos nao tabelados


30 Write(*,*)' Deseja determinar valores da funcao para pontos&
& nao tabelados?(sim- s;nao- n)'
35 Read(*,*)detval
If(detval=='s')Then
Write(*,*)' Qual o valor de x?'
Read(*,*)xnt

!Escolha da equacao para determinacao do valor.


40 Write(*,*)' Quer determinar os valores pela equacao&
& teorica (clique t) ou pelo modelo obtido (clique m)?'
Read(*,*)calc
If(calc=='m')Then
!valores de y dados pelo modelo
ymx=0.0
Do j=1,ord+1
ymx=ymx+b(j)*xnt**(j-1)
End Do
If(opcao2=='f')Then
Write(30,*) xnt
Write(30,*)' y (pelo modelo)=', ymx
End If
Write(*,*)' y (pelo modelo)=', ymx
Else If(calc=='t')Then

!valores de y dados pela equacao teorica


Do i=1, nmax
ytx=Pol(xnt,ord,coef)
End Do
If(opcao2=='f')Then
Write(30,*)xnt
Write(*,*)' y (pela eq teorica)=', ytx
End If
Write(*,*)'y (pela eq teorica)=', ytx
Else
Write(*,*)'Letra errada!!'
Goto 40
End If
Else If(detval=='n')Then
Goto 50
Else
Write(*,*)' Letra errada!!'
Goto 30
End If

!erro de selecao

4 write(*,101)

101 FORMAT (10(/),T15,50('*')/T15,'*',T25,'Selecionou uma opcao inexistente'&


&,T64,'*'/T15,'*',T25,'Prima <Enter> e selecione de novo',T64,'*'&
&/T15,50('*'),10(/))
pause
goto 3

Write(*,102)
!menu continuar a utilizacao do programa
102 FORMAT (7(/),T10,65('#')/T10,'#',T24,'DESEJA CONTINUAR A UTILIZAR O
&
&PROGRAMA',T74,'#'/T10,65('#')/T10,'#',T74,'#'/T10,'#',T74,'#'/&
&T10,'#',T14,'Prima:',T27,'Para:',T74,'#'/T10,'#',T14,6('-'),T27,&
&39('-'),T74,'#'/T10,'#',T16,'S',T27,'Volta ao inicio e continua &
&a utilizar',T74,'#'/T10,'#',T74,'#'/T10,'#',T16,'N',T27,'Termina&
& a utilizacao e sai do programa',T74,'#'/T10,'#',T74,'#'/T10,'#'&
&,T74,'#'/T10,65('#'),7(/))

pause
read(*,*)q
if(q==3)then
Goto 3
else if(q==9)then
goto 50
else
goto 4
end if

50 Write(*,105)
105 format(T15,' Obrigado por utilizar este programa!',/,/,/,T25,'Antonio Rodrigues -
2002' ,/,/)

pause

End Program