?? errors.f90
字號:
nrmxl = rvec_norm2 ( n-l+1, a(l,l), 1 )
if ( nrmxl /= 0.0E+00 ) then
if ( a(l,l) /= 0.0E+00 ) then
nrmxl = sign ( nrmxl, a(l,l) )
end if
call sscal ( n-l+1, 1.0E+00 / nrmxl, a(l,l), 1 )
a(l,l) = 1.0E+00 + a(l,l)
!
! Apply the transformation to the remaining columns, updating the norms.
!
do j = l + 1, p
t = - sdot ( n-l+1, a(l,l), 1, a(l,j), 1 ) / a(l,l)
call saxpy ( n-l+1, t, a(l,l), 1, a(l,j), 1 )
if ( j >= pl .and. j <= pu ) then
if ( qraux(j) /= 0.0E+00 ) then
tt = 1.0E+00 - ( abs ( a(l,j) ) / qraux(j) )**2
tt = max ( tt, 0.0E+00 )
t = tt
tt = 1.0E+00 + 0.05E+00 * tt * ( qraux(j) / work(j) )**2
if ( tt /= 1.0E+00 ) then
qraux(j) = qraux(j) * sqrt ( t )
else
qraux(j) = rvec_norm2 ( n-l, a(l+1,j), 1 )
work(j) = qraux(j)
end if
end if
end if
end do
!
! Save the transformation.
!
qraux(l) = a(l,l)
a(l,l) = - nrmxl
end if
end if
end do
return
end
subroutine sqrsl ( a, lda, n, k, qraux, y, qy, qty, b, rsd, ab, job, info )
!*****************************************************************************80
!
!! SQRSL computes transformations, projections, and least squares solutions.
!
! Discussion:
!
! SQRSL requires the output of SQRDC.
!
! For K <= min(N,P), let AK be the matrix
!
! AK = ( A(JPVT(1)), A(JPVT(2)), ..., A(JPVT(K)) )
!
! formed from columns JPVT(1), ..., JPVT(K) of the original
! N by P matrix A that was input to SQRDC. If no pivoting was
! done, AK consists of the first K columns of A in their
! original order. SQRDC produces a factored orthogonal matrix Q
! and an upper triangular matrix R such that
!
! AK = Q * (R)
! (0)
!
! This information is contained in coded form in the arrays
! A and QRAUX.
!
! The parameters QY, QTY, B, RSD, and AB are not referenced
! if their computation is not requested and in this case
! can be replaced by dummy variables in the calling program.
! To save storage, the user may in some cases use the same
! array for different parameters in the calling sequence. A
! frequently occuring example is when one wishes to compute
! any of B, RSD, or AB and does not need Y or QTY. In this
! case one may identify Y, QTY, and one of B, RSD, or AB, while
! providing separate arrays for anything else that is to be
! computed.
!
! Thus the calling sequence
!
! call sqrsl ( a, lda, n, k, qraux, y, dum, y, b, y, dum, 110, info )
!
! will result in the computation of B and RSD, with RSD
! overwriting Y. More generally, each item in the following
! list contains groups of permissible identifications for
! a single calling sequence.
!
! 1. (Y,QTY,B) (RSD) (AB) (QY)
!
! 2. (Y,QTY,RSD) (B) (AB) (QY)
!
! 3. (Y,QTY,AB) (B) (RSD) (QY)
!
! 4. (Y,QY) (QTY,B) (RSD) (AB)
!
! 5. (Y,QY) (QTY,RSD) (B) (AB)
!
! 6. (Y,QY) (QTY,AB) (B) (RSD)
!
! In any group the value returned in the array allocated to
! the group corresponds to the last member of the group.
!
! Reference:
!
! Dongarra, Moler, Bunch and Stewart,
! LINPACK User's Guide,
! SIAM, (Society for Industrial and Applied Mathematics),
! 3600 University City Science Center,
! Philadelphia, PA, 19104-2688.
! ISBN 0-89871-172-X
!
! Parameters:
!
! Input, real A(LDA,P), contains the output of SQRDC.
!
! Input, integer LDA, the leading dimension of the array A.
!
! Input, integer N, the number of rows of the matrix AK. It must
! have the same value as N in SQRDC.
!
! Input, integer K, the number of columns of the matrix AK. K
! must not be greater than min(N,P), where P is the same as in the
! calling sequence to SQRDC.
!
! Input, real QRAUX(P), the auxiliary output from SQRDC.
!
! Input, real Y(N), a vector to be manipulated by SQRSL.
!
! Output, real QY(N), contains Q * Y, if requested.
!
! Output, real QTY(N), contains Q' * Y, if requested.
!
! Output, real B(K), the solution of the least squares problem
! minimize norm2 ( Y - AK * B),
! if its computation has been requested. Note that if pivoting was
! requested in SQRDC, the J-th component of B will be associated with
! column JPVT(J) of the original matrix A that was input into SQRDC.
!
! Output, real RSD(N), the least squares residual Y - AK * B,
! if its computation has been requested. RSD is also the orthogonal
! projection of Y onto the orthogonal complement of the column space
! of AK.
!
! Output, real AB(N), the least squares approximation Ak * B, if its
! computation has been requested. AB is also the orthogonal projection
! of Y onto the column space of A.
!
! Input, integer JOB, specifies what is to be computed. JOB has
! the decimal expansion ABCDE, with the following meaning:
!
! if A /= 0, compute QY.
! if B /= 0, compute QTY.
! if C /= 0, compute QTY and B.
! if D /= 0, compute QTY and RSD.
! if E /= 0, compute QTY and AB.
!
! Note that a request to compute B, RSD, or AB automatically triggers
! the computation of QTY, for which an array must be provided in the
! calling sequence.
!
! Output, integer INFO, is zero unless the computation of B has
! been requested and R is exactly singular. In this case, INFO is the
! index of the first zero diagonal element of R, and B is left unaltered.
!
implicit none
integer k
integer lda
integer n
real a(lda,*)
real ab(n)
real b(k)
logical cab
logical cb
logical cqty
logical cqy
logical cr
logical cxb
integer i
integer info
integer j
integer jj
integer job
integer ju
integer kp1
real qraux(*)
real qty(n)
real qy(n)
real rsd(n)
real sdot
real t
real temp
real y(n)
!
! set info flag.
!
info = 0
!
! Determine what is to be computed.
!
cqy = job / 10000 /= 0
cqty = mod ( job, 10000 ) /= 0
cb = mod ( job, 1000 ) / 100 /= 0
cr = mod ( job, 100 ) / 10 /= 0
cab = mod ( job, 10 ) /= 0
ju = min ( k, n-1 )
!
! Special action when N = 1.
!
if ( ju == 0 ) then
if ( cqy ) then
qy(1) = y(1)
end if
if ( cqty ) then
qty(1) = y(1)
end if
if ( cab ) then
ab(1) = y(1)
end if
if ( cb ) then
if ( a(1,1) == 0.0E+00 ) then
info = 1
else
b(1) = y(1) / a(1,1)
end if
end if
if ( cr ) then
rsd(1) = 0.0E+00
end if
return
end if
!
! Set up to compute QY or QTY.
!
if ( cqy ) then
qy(1:n) = y(1:n)
end if
if ( cqty ) then
qty(1:n) = y(1:n)
end if
!
! Compute QY.
!
if ( cqy ) then
do jj = 1, ju
j = ju - jj + 1
if ( qraux(j) /= 0.0E+00 ) then
temp = a(j,j)
a(j,j) = qraux(j)
t = - sdot ( n-j+1, a(j,j), 1, qy(j), 1 ) / a(j,j)
call saxpy ( n-j+1, t, a(j,j), 1, qy(j), 1 )
a(j,j) = temp
end if
end do
end if
!
! Compute Q'*Y.
!
if ( cqty ) then
do j = 1, ju
if ( qraux(j) /= 0.0E+00 ) then
temp = a(j,j)
a(j,j) = qraux(j)
t = - sdot ( n-j+1, a(j,j), 1, qty(j), 1 ) / a(j,j)
call saxpy ( n-j+1, t, a(j,j), 1, qty(j), 1 )
a(j,j) = temp
end if
end do
end if
!
! Set up to compute B, RSD, or AB.
!
if ( cb ) then
b(1:k) = qty(1:k)
end if
kp1 = k + 1
if ( cab ) then
ab(1:k) = qty(1:k)
end if
if ( cr .and. k < n ) then
rsd(k+1:n) = qty(k+1:n)
end if
if ( cab .and. k+1 <= n ) then
ab(k+1:n) = 0.0E+00
end if
if ( cr ) then
rsd(1:k) = 0.0E+00
end if
!
! Compute B.
!
if ( cb ) then
do jj = 1, k
j = k - jj + 1
if ( a(j,j) == 0.0E+00 ) then
info = j
exit
end if
b(j) = b(j)/a(j,j)
if ( j /= 1 ) then
t = -b(j)
call saxpy ( j-1, t, a(1,j), 1, b, 1 )
end if
end do
end if
if ( cr .or. cab ) then
!
! Compute RSD or AB as required.
!
do jj = 1, ju
j = ju - jj + 1
if ( qraux(j) /= 0.0E+00 ) then
temp = a(j,j)
a(j,j) = qraux(j)
if ( cr ) then
t = - sdot ( n-j+1, a(j,j), 1, rsd(j), 1 ) / a(j,j)
call saxpy ( n-j+1, t, a(j,j), 1, rsd(j), 1 )
end if
if ( cab ) then
t = - sdot ( n-j+1, a(j,j), 1, ab(j), 1 ) / a(j,j)
call saxpy ( n-j+1, t, a(j,j), 1, ab(j), 1 )
end if
a(j,j) = temp
end if
end do
end if
return
end
subroutine sscal ( n, sa, x, incx )
!*****************************************************************************80
!
!! SSCAL scales a vector by a constant.
!
! Modified:
!
! 08 April 1999
!
! Parameters:
!
! Input, integer N, the number of entries in the vector.
!
! Input, real SA, the multiplier.
!
! Input/output, real X(*), the vector to be scaled.
!
! Input, integer INCX, the increment between successive entries of X.
!
implicit none
integer i
integer incx
integer ix
integer m
integer n
real sa
real x(*)
if ( n <= 0 ) then
else if ( incx == 1 ) then
m = mod ( n, 5 )
do i = 1, m
x(i) = sa * x(i)
end do
do i = m+1, n, 5
x(i) = sa * x(i)
x(i+1) = sa * x(i+1)
x(i+2) = sa * x(i+2)
x(i+3) = sa * x(i+3)
x(i+4) = sa * x(i+4)
end do
else
if ( incx >= 0 ) then
ix = 1
else
ix = ( - n + 1 ) * incx + 1
end if
do i = 1, n
x(ix) = sa * x(ix)
ix = ix + incx
end do
end if
return
end
subroutine sswap ( n, x, incx, y, incy )
!*****************************************************************************80
!
!! SSWAP interchanges two vectors.
!
! Modified:
!
! 08 April 1999
!
! Parameters:
!
! Input, integer N, the number of entries in the vectors.
!
! Input/output, real X(*), one of the vectors to swap.
!
! Input, integer INCX, the increment between successive entries of X.
!
! Input/output, real Y(*), one of the vectors to swap.
!
! Input, integer INCY, the increment between successive elements of Y.
!
implicit none
integer i
integer incx
integer incy
integer ix
integer iy
integer m
integer n
real stemp
real x(*)
real y(*)
if ( n <= 0 ) then
else if ( incx == 1 .and. incy == 1 ) then
m = mod ( n, 3 )
do i = 1, m
stemp = x(i)
x(i) = y(i)
y(i) = stemp
end do
do i = m+1, n, 3
stemp = x(i)
x(i) = y(i)
y(i) = stemp
stemp = x(i + 1)
x(i + 1) = y(i + 1)
y(i + 1) = stemp
stemp = x(i + 2)
x(i + 2) = y(i + 2)
y(i + 2) = stemp
end do
else
if ( incx >= 0 ) then
ix = 1
else
ix = ( - n + 1 ) * incx + 1
end if
if ( incy >= 0 ) then
iy = 1
else
iy = ( - n + 1 ) * incy + 1
end if
do i = 1, n
stemp = x(ix)
x(ix) = y(iy)
y(iy) = stemp
ix = ix + incx
iy = iy + incy
end do
end if
return
end
subroutine timestamp ( )
!
!*****************************************************************************80
!
!! TIMESTAMP prints the current YMDHMS date as a time stamp.
!
!
! Example:
!
! May 31 2001 9:45:54.872 AM
!
! Modified:
!
! 31 May 2001
!
! Author:
!
! John Burkardt
!
! Parameters:
!
! None
!
implicit none
character ( len = 8 ) ampm
integer d
character ( len = 8 ) date
integer h
integer m
integer mm
character ( len = 9 ), parameter, dimension(12) :: month = (/ &
'January ', 'February ', 'March ', 'April ', &
'May ', 'June ', 'July ', 'August ', &
'September', 'October ', 'November ', 'December ' /)
integer n
integer s
character ( len = 10 ) time
integer values(8)
integer y
character ( len = 5 ) zone
call date_and_time ( date, time, zone, values )
y = values(1)
m = values(2)
d = values(3)
h = values(5)
n = values(6)
s = values(7)
mm = values(8)
if ( h < 12 ) then
ampm = 'AM'
else if ( h == 12 ) then
if ( n == 0 .and. s == 0 ) then
ampm = 'Noon'
else
ampm = 'PM'
end if
else
if ( h < 12 ) then
ampm = 'PM'
else if ( h == 12 ) then
if ( n == 0 .and. s == 0 ) then
ampm = 'Midnight'
else
ampm = 'AM'
end if
end if
end if
write ( *, '(a,1x,i2,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) &
trim ( month(m) ), d, y, h, ':', n, ':', s, '.', mm, trim ( ampm )
return
end
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -