FreeBSD/contrib/ntp/ntpd/refclock_wwv.c
/*
 * wwv_corr4 - determine maximum-likelihood digit
 *
 * This routine correlates the received digit vector with the BCD
 * coefficient vectors corresponding to all valid digits at the given
 * position in the decoding matrix. The maximum value corresponds to the
 * maximum-likelihood digit, while the ratio of this value to the next
 * lower value determines the likelihood function. Note that, if the
 * digit is invalid, the likelihood vector is averaged toward a miss.
 */
determine maximum-likelihood digit
This routine correlates the received digit vector with the BCD
coefficient vectors corresponding to all valid digits at the given
position in the decoding matrix. The maximum value corresponds to the
maximum-likelihood digit, while the ratio of this value to the next
lower value determines the likelihood function. Note that, if the
digit is invalid, the likelihood vector is averaged toward a miss.
determine maximum - likelihood digit This routine correlates the received digit vector with the BCD coefficient vectors corresponding to all valid digits at the given position in the decoding matrix . The maximum value corresponds to the maximum - likelihood digit while the ratio of this value to the next lower value determines the likelihood function . Note that if the digit is invalid the likelihood vector is averaged toward a miss .
static void
wwv_corr4(
	struct peer *peer,	
	struct decvec *vp,	
	double	data[],		
	double	tab[][4]	
	)
{
	struct refclockproc *pp;
	struct wwvunit *up;
	double	topmax, nxtmax;	
	double	acc;		
	char	tbuf[TBUF];	
	int	mldigit;	
	int	i, j;
	pp = peer->procptr;
	up = pp->unitptr;
	mldigit = 0;
	topmax = nxtmax = -MAXAMP;
	for (i = 0; tab[i][0] != 0; i++) {
		acc = 0;
		for (j = 0; j < 4; j++)
			acc += data[j] * tab[i][j];
		acc = (vp->like[i] += (acc - vp->like[i]) / TCONST);
		if (acc > topmax) {
			nxtmax = topmax;
			topmax = acc;
			mldigit = i;
		} else if (acc > nxtmax) {
			nxtmax = acc;
		}
	}
	vp->digprb = topmax;
	vp->digsnr = wwv_snr(topmax, nxtmax);
	if (vp->digprb < BTHR || vp->digsnr < BSNR) {
		up->status |= BGATE;
	} else {
		if (vp->digit != mldigit) {
			up->alarm |= CMPERR;
			if (vp->count > 0)
				vp->count--;
			if (vp->count == 0)
				vp->digit = mldigit;
		} else {
			if (vp->count < BCMP)
				vp->count++;
			if (vp->count == BCMP) {
				up->status |= DSYNC;
				up->digcnt++;
			}
		}
	}
	if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status &
	    INSYNC)) {
		snprintf(tbuf, sizeof(tbuf),
		    "wwv4 %2d %04x %3d %4d %5.0f %2d %d %d %d %5.0f %5.1f",
		    up->rsec - 1, up->status, up->gain, up->yepoch,
		    up->epomax, vp->radix, vp->digit, mldigit,
		    vp->count, vp->digprb, vp->digsnr);
		record_clock_stats(&peer->srcadr, tbuf);
#ifdef DEBUG
		if (debug)
			printf("%s\n", tbuf);
#endif 
	}
}
static void wwv_corr4 ( struct peer * peer , struct decvec * vp , double data [ ] , double tab [ ] [ 4 ] ) { struct refclockproc * pp ; struct wwvunit * up ; double topmax , nxtmax ; double acc ; char tbuf [ TBUF ] ; int mldigit ; int i , j ; pp = peer -> procptr ; up = pp -> unitptr ; mldigit = 0 ; topmax = nxtmax = - MAXAMP ; for ( i = 0 ; tab [ i ] [ 0 ] != 0 ; i ++ ) { acc = 0 ; for ( j = 0 ; j < 4 ; j ++ ) acc += data [ j ] * tab [ i ] [ j ] ; acc = ( vp -> like [ i ] += ( acc - vp -> like [ i ] ) / TCONST ) ; if ( acc > topmax ) { nxtmax = topmax ; topmax = acc ; mldigit = i ; } else if ( acc > nxtmax ) { nxtmax = acc ; } } vp -> digprb = topmax ; vp -> digsnr = wwv_snr ( topmax , nxtmax ) ; if ( vp -> digprb < BTHR || vp -> digsnr < BSNR ) { up -> status |= BGATE ; } else { if ( vp -> digit != mldigit ) { up -> alarm |= CMPERR ; if ( vp -> count > 0 ) vp -> count -- ; if ( vp -> count == 0 ) vp -> digit = mldigit ; } else { if ( vp -> count < BCMP ) vp -> count ++ ; if ( vp -> count == BCMP ) { up -> status |= DSYNC ; up -> digcnt ++ ; } } } if ( ( pp -> sloppyclockflag & CLK_FLAG4 ) && ! ( up -> status & INSYNC ) ) { snprintf ( tbuf , sizeof ( tbuf ) , " " , up -> rsec - 1 , up -> status , up -> gain , up -> yepoch , up -> epomax , vp -> radix , vp -> digit , mldigit , vp -> count , vp -> digprb , vp -> digsnr ) ; record_clock_stats ( & peer -> srcadr , tbuf ) ; #ifdef DEBUG if ( debug ) printf ( " \n " , tbuf ) ; #endif } }
wwv_corr4 - determine maximum-likelihood digit
 This routine correlates the received digit vector with the BCD
 coefficient vectors corresponding to all valid digits at the given
 position in the decoding matrix.
wwv_corr4 - determine maximum - likelihood digit This routine correlates the received digit vector with the BCD coefficient vectors corresponding to all valid digits at the given position in the decoding matrix .
/* peer unit pointer */ /* decoding table pointer */ /* received data vector */ /* correlation vector array */ /* metrics */ /* accumulator */ /* monitor buffer */ /* max likelihood digit */ /*
	 * Correlate digit vector with each BCD coefficient vector. If
	 * any BCD digit bit is bad, consider all bits a miss. Until the
	 * minute units digit has been resolved, don't to anything else.
	 * Note the SNR is calculated as the ratio of the largest
	 * likelihood value to the next largest likelihood value.
 	 */ /*
	 * The current maximum-likelihood digit is compared to the last
	 * maximum-likelihood digit. If different, the compare counter
	 * and maximum-likelihood digit are reset.  When the compare
	 * counter reaches the BCMP threshold (3), the digit is assumed
	 * correct. When the compare counter of all nine digits have
	 * reached threshold, the clock is assumed correct.
	 *
	 * Note that the clock display digit is set before the compare
	 * counter has reached threshold; however, the clock display is
	 * not considered correct until all nine clock digits have
	 * reached threshold. This is intended as eye candy, but avoids
	 * mistakes when the signal is low and the SNR is very marginal.
	 */ /* DEBUG */