smpgn.f
上传用户:szhypcb168
上传日期:2007-01-06
资源大小:2187k
文件大小:4k
- c==========================================================================
- c
- c ROUTINE
- c smoothpgain
- c
- c FUNCTION
- c
- c smooth pgain values when two errors detected in
- c Hamming block
- c
- c SYNOPSIS
- c smoothpgain(pgain,twoerror,syndavg)
- c
- c formal
- c
- c data I/O
- c name type type function
- c -------------------------------------------------------------------
- c pgain real i/o input pgain
- c twoerror log i two error flag
- c syndavg real i error rate estimation parameter
- c pgains real i vector of pgains to calculate variance
- c subframe int i subframe number
- c
- c==========================================================================
- c
- c DESCRIPTION
- c
- c Smoothing routine to smooth pgain (alpha) when errors are detected:
- c
- c Due to the range of PGAIN, statistical variance is not appropriate.
- c Pseudovariance is used and calculated as:
- c sum of delta oldpgains/# of deltas
- c
- c If this variance of past pgain values is within the range VARLIMIT,
- c the validity of the current pgain value is tested. If the current
- c value of pgain is within the range PGAINLIMIT, PGAIN is passed.
- c If PGAIN is not within that range it is reset to the average
- c value of surrounding pgain values.
- c
- c The array OLDPGAIN contains past values of pgain. The array
- c PGAINS contains current and future values of pgain. The array
- c VECTOR is constructed from the arrays OLDPGAIN and PGAINS
- c depending on the current subframe. PGAIN is smoothed based on
- c the statistics of VECTOR, which contains the nearest four
- c surrounding pgain values, both past and future values, except
- c where future values are not available (subframes 3 and 4).
- c
- c Absolute values of pgain are used in averaging and reassigning
- c pgain. All reassigned pgains are limited to the range 0.0-1.0.
- c
- c Note: The smoothing parameters should be capable of adapting
- c to various bit error rate estimates. For example, different
- c values of SYNDAVG should select different levels of PGAINLIMIT,
- c VARLIMIT, and SYNDLIMIT.
- c
- c
- c**************************************************************************
- c
- subroutine smoothpgain(pgain,twoerror,syndavg,pgains,subframe)
- implicit undefined(a-z)
- c
- real pgain,syndavg,pgains(4)
- logical twoerror,enable
- include 'ccsub.com'
- convex #include "ccsub.com"
- integer pgainhistory
- parameter (pgainhistory=4)
- real oldpgain(pgainhistory),varlimit,pgainlimit,abspgain
- integer i,subframe
- real avg,var,sum1,sum2,vector(4),syndlimit
- c
- save oldpgain,enable
- c
- parameter (pgainlimit=0.9)
- parameter (varlimit=0.2)
- parameter (syndlimit=0.04)
- c
- abspgain=abs(pgain)
- if (subframe .ne. 4) enable = .true.
- if ((twoerror .or. syndavg.gt.syndlimit) .and. enable) then
- if (subframe .eq. 1) then
- vector(1)=oldpgain(1)
- vector(2)=oldpgain(2)
- vector(3)=abs(pgains(2))
- vector(4)=abs(pgains(3))
- else if (subframe .eq. 2) then
- vector(1)=oldpgain(1)
- vector(2)=oldpgain(2)
- vector(3)=abs(pgains(3))
- vector(4)=abs(pgains(4))
- else if (subframe .eq. 3) then
- vector(1)=oldpgain(1)
- vector(2)=oldpgain(2)
- vector(3)=oldpgain(3)
- vector(4)=abs(pgains(4))
- else if (subframe .eq. 4) then
- vector(1)=oldpgain(1)
- vector(2)=oldpgain(2)
- vector(3)=oldpgain(3)
- vector(4)=oldpgain(4)
- else
- print *,' smoothpgain: Error in subframe number'
- end if
- sum1=0.
- do 10 i=1,pgainhistory
- sum1=sum1+vector(i)
- 10 continue
- avg=sum1/float(pgainhistory)
- sum2=0.
- do 20 i=1,pgainhistory-1
- sum2=sum2+abs(vector(i)-vector(i+1))
- 20 continue
- var=sum2/float(pgainhistory-1)
- if ((var.lt.varlimit) .and. enable) then
- if (abspgain.gt.avg+pgainlimit .or.
- 1 abspgain.lt.avg-pgainlimit) then
- pgain=avg
- if (pgain.gt.1.0) pgain=1.0
- if (pgain.lt.-1.0) pgain=-1.0
- print *,' smoothpgain: pgain value reset to avg',
- & ' at frame', frame,' subframe', subframe
- if (subframe .eq. 3) then
- enable = .false.
- print *,' smoothpgain: smoothing disabled for subframe 4'
- end if
- end if
- end if
- end if
- do 30 i=pgainhistory-1,1,-1
- oldpgain(i+1)=oldpgain(i)
- 30 continue
- oldpgain(1)=abspgain
- return
- end