W Edwards Deming was an American statistician and management guru who used physical demonstrations to illuminate his teachings. In one demonstration Deming repeatedly dropped marbles through a funnel at a target, marking where they landed, and observing the resulting pattern. He applied a sequence of "rules" to try to improve performance. In each case the experiment begins with the funnel positioned directly over the target.

 Rule 1: The funnel remains directly above the target.
 Rule 2: Adjust the funnel position by shifting the target to compensate after each drop. E.g. If the last drop missed 1 cm east, move the funnel 1 cm to the west of its current position.
 Rule 3: As rule 2, but first move the funnel back over the target, before making the adjustment. E.g. If the funnel is 2 cm north, and the marble lands 3 cm north, move the funnel 3 cm south of the target.
 Rule 4: The funnel is moved directly over the last place a marble landed.
Apply the four rules to the set of 50 pseudorandom displacements provided (e.g in the Racket solution) for the dxs and dys. Output: calculate the mean and standard-deviations of the resulting x and y values for each rule.

Note that rules 2, 3, and 4 give successively worse results. Trying to deterministically compensate for a random process is counter-productive, but -- according to Deming -- quite a popular pastime: see the Further Information, below for examples.

Stretch goal 1: Generate fresh pseudorandom data. The radial displacement of the drop from the funnel position is given by a Gaussian distribution (standard deviation is 1.0) and the angle of displacement is uniformly distributed.

Stretch goal 2: Show scatter plots of all four results.



Further information

 Further explanation and interpretation
 Video demonstration of the funnel experiment at the Mayo Clinic.
fcn funnel(dxs, rule){
   x:=0.0; rxs:=L();
   foreach dx in (dxs){
      rxs.append(x + dx);
      x = rule(x,dx);
   }
   rxs
}
 
fcn mean(xs){ xs.sum(0.0)/xs.len() }
 
fcn stddev(xs){
   m:=mean(xs);
   (xs.reduce('wrap(sum,x){ sum + (x-m)*(x-m) },0.0)/xs.len()).sqrt();
}
 
fcn experiment(label,dxs,dys,rule){
   rxs:=funnel(dxs,rule); rys:=funnel(dys,rule);
   label.println();
   "Mean x, y    : %7.4f, %7.4f".fmt(mean(rxs),  mean(rys))  .println();
   "Std dev x, y : %7.4f, %7.4f".fmt(stddev(rxs),stddev(rys)).println();
   println();
}