You are on page 1of 7

Math 697NA Numerical Algorithms

HW 3
Pb1:
program hw3

!!!!!!! variable declaration


implicit none
integer :: i,N,M,j,k
integer :: scheme
double precision :: xi,yi,norm2,sovp
double precision, dimension(:,:), allocatable :: A,cA,C,D,Q,R,
double precision,dimension(:),allocatable :: b,y,res,x,gx,gy
!! for LAPACK
integer :: info,lwork
double precision,dimension(:),allocatable :: work
character(len=1) :: ext
!!!!!!!

!!!!!!!

print *,"Select Scheme (1: LAPACK/Householder ,2: Normal equation, 3: GS):"


read *,scheme

print *,"Enter degree of approximation n:"


read *,n

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!! Uniform M points in[-1:1] !!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
M=50
allocate(x(1:M))
do i=1,M
x(i)=-1.0d0+2.0d0*((i-1)/(M*1.0d0-1.0d0))
enddo

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!! Fucntion f(x) = 1/(1+25*x^2) M points in[-1:1] !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
allocate(b(1:M))
b = 1.0d0/(1.0d0 + 25.0d0*(x**2));

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!! Formation of matrix A and rhs !!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
allocate(A(M,N)) ! matrix (dense storage)

do i=1,M
do j=1,n
A(i,j) = x(i)**(j-1)
end do
end do

!!!! save rhs for plotting


allocate(y(M))
y=b
!!!! save matrix for residual calculation
allocate(cA(1:M,1:N))
cA=A

select case(scheme)

case(1)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!! LAPACK Householder solution !!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ext="1" ! for output file
WRITE(*,*)'LAPACK Householder Program Result'
!!optimal workspace
lwork = max(1,M*N+max(M*N,1))
allocate(work(lwork))
CALL DGELS('N', M, N, 1, A, M, B, M, work, lwork, info)

case(2)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!! Normal eqation !!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ext="2" ! for ouptut file
WRITE(*,*)'Normal Equation Program Result'
!!Perform A**T A x = A**T b, let C = A**T A
allocate(c(N,N))
call DGEMM('T', 'N', N, N, M, 1.0d0, A, M, A, M, 0.0d0, C, N)
allocate(d(N,1))
call DGEMM('T', 'N', N, 1, M, 1.0d0, A, M, B, M, 0.0d0, D, N)
call DPOSV('L', N, 1, C, N, D, N, info)
do i=1,N
b(i)=d(i,1)
end do

case(3)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!! Using modified GS in place!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ext="3" ! for ouptut file
WRITE(*,*)'Modified Gram-schmidt Program Result'
allocate(C(M,N))
allocate(D(N,1))
allocate(Q(M,N))
allocate(R(N,N))

do j=1,n
do i=1,m
q(i,j) = a(i,j) !filling Q matrix
end do
end do
!!calculate norm
do k=1,n
norm2 = 0.
do i=1,m
norm2 = norm2 + q(i,k)**2
end do
r(k,k) = sqrt(norm2) !r_ii = norm(q_k)
do i=1,m
q(i,k) = q(i,k)/r(k,k)
end do
!! next steps - calculate vector product
do j=(k+1),n
sovp = 0.
do i=1,m
sovp = sovp+(q(i,j)*q(i,k)) !calculating q_jq_k
end do
r(k,j) = sovp !calculating r_ij
do i=1,m
q(i,j)=q(i,j)-r(k,j)*q(i,k) !calculating q_ij
end do
end do
end do

call DGEMM('N', 'N', M, N, N, 1.0d0, Q, M, R, N, 0.0d0, C, M) !to check if A = QR


call DGEMM('T', 'N', N, N, M, 1.0d0, Q, M, b, M, 0.0d0, D, N) !to solve Q'b = d
call DTRSM('L', 'U', 'N', 'N', N, 1, 1.0d0, R, N, D, N) !to solve Rx=d
do i=1,N
b(i)=d(i,1)
end do

end select
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!! Results!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! ATTENTION Here the first N rows of vector b must contain the solution
!!!!!!! Polynomial approximation
print *,''
print *,'Coefficents ai of polynomial approximation g(x)=a1+a2*x+...+an*x^(n-1):'
do i=1,n
print *,b(i)
enddo
!!!!!! Check norm 2 Residual of solution
allocate(res(M))
res=y
call DGEMM('N','N',M, 1, N, 1.0d0, cA, M, b, M, -1.0d0, res, M ) !! BLAS function
print *,"Relative Residual is",sqrt(sum(abs(res)**2))/sqrt(sum(abs(y)**2))
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!! Save results !!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! save data points for function f(x)
open(10,file='data',status='replace')
do i=1,M
write(10,*) x(i),y(i)
end do
close(10)
!! save the numerical solution- fitting with polynomial g(x)
!! we use a large number of points to get a smooth curve
!! let us say: 10*M points
allocate(gx(10*M))
allocate(gy(10*M))
open(10,file='fit'//ext,status='replace')
do i=1,10*M
gx(i)=-1.0d0+2.0d0*((i-1)/(10*M*1.0d0-1.0d0))
do j=1,n
gy(i)= b(j)*gx(i)**(j-1)
end do
write(10,*) gx(i),gy(i)
end do
close(10)
end program hw3

Pb2:
F(x) vs. Curve fits
Curve with degree 15 does not give a good fit.

Pb3: Reisduals vs. N


Comments:
1) Householder transformation is the most robust algorithm
2) Normal equation suffers from ill-conditioning as N increases and eventually
breaks for N > 20
3) Gram-Schmidt suffers from round-off error breaks for relatively low values
of N.

You might also like