aboutsummaryrefslogtreecommitdiff
path: root/pkg/lists/average.cl
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lists/average.cl')
-rw-r--r--pkg/lists/average.cl56
1 files changed, 56 insertions, 0 deletions
diff --git a/pkg/lists/average.cl b/pkg/lists/average.cl
new file mode 100644
index 00000000..d6d12b6e
--- /dev/null
+++ b/pkg/lists/average.cl
@@ -0,0 +1,56 @@
+#{ AVERAGE -- Compute the average and standard deviation of a list of numbers.
+# Numeric input is via the standard input (one number per line). The mean,
+# sigma, and number of samples are written to the standard output.
+#
+# By default (Average called with no arguments), the sample is taken
+# to be the set of numbers in the standard input when Average is run.
+# Additional points can be added to or deleted from the sample by
+# rerunning Average with one of the following arguments:
+#
+# add - add points to the sample, recalculate mean and sigma
+# sub - subtract points from the sample
+
+
+{
+ if ($nargs == 0) # if no arguments, don't query
+ opstring = "new_sample"
+ else
+ opstring = option # get parameter "option"
+
+
+ if (opstring == "add") # add, subtract, or start over?
+ addsub_flag = 1
+ else if (opstring == "sub" || opstring == "subtract")
+ addsub_flag = -1
+ else { # new sample (default)
+ addsub_flag = 1
+ n = 0 # number of points in sample
+ sum = 0
+ sumsqrs = 0
+ }
+
+
+ # Process data; print mean, sigma, and the sample size on
+ # the standard output.
+
+ while (scan (data_value) != EOF)
+ if (nscan() == 1 && data_value != INDEF) {
+ n += addsub_flag
+ sum += addsub_flag * data_value
+ sumsqrs += addsub_flag * data_value * data_value
+ }
+
+ if (n <= 0)
+ print ("INDEF ", "INDEF ", n)
+ else if (n == 1)
+ print (sum, "INDEF ", 1)
+ else {
+ mean = sum / n
+ variance = (n * sumsqrs - sum * sum) / (n * (n-1))
+ if (variance < 0) # possible with roundoff error
+ sigma = 0.0
+ else
+ sigma = sqrt (variance)
+ print (mean, sigma, n)
+ }
+}