The clockfilter procedure is executed upon arrival of an NTP message or other event that results in new data samples. It takes arguments of the form theta, delta, epsilon, where theta is a sample clock offset measurement and delta and epsilon are the associated roundtrip delay
and dispersion. It determines the filtered clock offset (peer.offset), roundtrip delay (peer.delay) and dispersion (peer.dispersion). It also updates the dispersion of samples already recorded and saves the current time (peer.update).
The basis of the clockfilter procedure is the filter shift register (peer.filter), which consists of NTP.SHIFT stages, each stage containing a 3tuple [ theta sub i , delta sub i , epsilon sub i ], with indices numbered from zero on the left. The filter is initialized with the
value [0,0, NTP.MAXDISPERSE] in all stages by the clear procedure. New data samples are shifted into the filter at the left end, causing first NULLs then old samples to fall off the right end. The packet procedure provides samples of the form [theta, delta, epsilon] as new updates arrive, while the
transmit procedure provides samples of the form [0,0, NTP.MAXDISPERSE] when two poll intervals elapse without a fresh update. While the same symbols (theta ,delta ,epsilon) are used here for the arguments, clockfilter contents and peer variables, the meaning will be clear from context. The
following pseudocode describes this procedure.
begin clockfilter procedure (theta ,delta ,epsilon)
The dispersion epsilon sub i for all valid samples in the filter register must be updated to account for the skewerror accumulation since the last update. These samples are also inserted on a temporary list with entry format [distance,index]. The samples in the register are
shifted right one stage, with the overflow sample discarded and the new sample inserted at the leftmost stage. The temporary list is then sorted by increasing distance. If no samples remain in the list, the procedure exits without updating the peer variables.
for (i from NTP.SIZE  1 to 1) begin /* update dispersion */
[ theta sub i ,delta sub i ,epsilon sub i ] < [theta sub {i1} ,delta sub {i1} ,epsilon sub {i1}
];
/* shift stage right */
epsilon sub i = epsilon sub i + phi tau;
add [ lambda sub i == epsilon sub i + { delta sub i } over 2 , i] to temporary list;
endfor;
[ theta sub 0 ,delta sub 0 ,epsilon sub 0 ] < [ theta ,delta ,epsilon ]; /* insert new sample */
add [ lambda == epsilon + { delta } over 2 ,0] to temporary list;
peer.update < sys.clock; /* reset base time */
sort temporary list by increasing [distance index];
where [distance index] represents the concatenation of the distance and index fields and distance is the highorder field. The filter dispersion epsilon sub sigma is computed and included in the peer dispersion. Note that for this purpose the temporary list is already
sorted.
epsilon sub sigma < 0;
for (i from NTP.SHIFT  1 to 0) /* compute filter dispersion */
if (peer.dispersion sub index[i] >= NTP.MAXDISPERSE or
 theta sub i  theta sub 0  > NTP.MAXDISPERSE
epsilon sub sigma < epsilon sub sigma + NTP.MAXDISPERSE) times NTP.FILTER;
else
epsilon sub sigma < ( epsilon sub sigma +  theta sub i  theta sub 0 ) times NTP.FILTER;
The peer offset theta sub 0, delay delta sub 0 and dispersion epsilon sub 0 are chosen as the values corresponding to the minimumdistance sample; in other words, the sample corresponding to the first entry on the temporary list, here represented as the 0th subscript.
peer.offset < theta sub 0; /* update peer variables */
peer.delay < delta sub 0;
peer.dispersion < min ( epsilon sub 0 + epsilon sub sigma , NTP.MAXDISPERSE);
end clockfilter procedure
The peer.offset and peer.delay variables represent the clock offset and roundtrip delay of the local clock relative to the peer clock. Both of these are precision quantities and can usually be averaged over long intervals in order to improve accuracy and stability without bias
accumulation (see Appendix H). The peer.dispersion variable represents
the maximum error due to measurement error, skewerror accumulation and sample variance. All three variables are used in the clockselection and clockcombining procedures to select the peer clock(s) used for synchronization and to maximize the accuracy and stability of the
indications.
