The standard *girl* library is a collection of macros, transducers, and signal
procedures that are sufficiently useful that they ought to be standardized. It is
implemented in the package girl-library and it exports the
following bindings:

There are a number of predefined group types that are used to represent vectors. These are used when one wants to think of the elements of the vector as having names (x, y, z) rather than numeric indicies. It allows code to distinguish syntactically between Cartesian and polar vectors, for example.

## xy-vectors and polar-vectors

xy-vectors are used to represent 2D Cartesian coordinate vectors. polar-vectors are used to represent 2D polar coordinate vectors. The accessors for each have been hacked to accept either type of vector.

- (xy-vector
*x y*) - (polar-vector
*angle magnitude*) - Constructors

- (x-of
*vector*) - (y-of
*vector*) - (angle
*vector*) - (magnitude
*vector*) - Accessors.
- (polar->xy
*polar-vector*) - (xy->polar
*xy-vector*) - Type conversion.

- (squared-magnitude
*vector*) - The squared magnitude
*vector*. - (rotate-xy-vector
*xy-vector radians*) - Rotates an xy-vector by the specified angle.

## rt-vectors

rt-vectors are used to represent rotational and translational velocities.

- (rt-vector
*rotation translation*) - Constructor
- (rotation-of
*rt-vector*) - (translation-of
*rt-vector*) - Accessors

- (rt->xy
*rt-vector*) - (xy->rt
*xy-vector*) - Type conversion. These behave the same as xy->polar and polar->xy, but happen to use rt-vectors. Note that technically these two data types represent incommensurable quantities, so these operations don't make sense as real type conversions. None the less, they're fairly commonly used so they're provided here.

## lines

mxb-lines are used to represent lines in slope/intercept format. At some point, we'll add other parameterizations.

- (mxb-line
*slope intercept*) - Constructor
- (line-slope
*line*) - (line-intercept
*line*) - Accessors

- (points->line
*point1 point2*) - Fits a line to two points. Presently, requires that the line have finite slope.
- (line-intersection
*line1 line2*) - Fits a line to two points. Presently, requires that the line have finite slope.
- (point-line-distance
*point line*) - Returns the (vertical) distance between the point and line.

## Intervals

Intervals represent closed intervals in the range [*min*, *max*].

- (interval
*min max*) - (point-interval
*value*) - (empty-interval)
- (range
*value ...*) - Constructors for intervals.

- (interval-min
*interval*)

(interval-max*interval*) - Basic accessors for intervals

- (interval-empty?
*interval*) - (interval-member?
*value interval*) - The only useful predicates I could think of on intervals.

(interval-size*interval*)

(interval-midpoint*interval*)- Self-explanatory

(interval-+*interval1 interval2*)

(interval--*interval1 interval2*)

(interval-**interval1 interval2*)

(interval-negate*interval*)- Arithmetic operators on intervals
- (interval-intersection
*interval1 interval2*)

(interval-union*interval1 interval2*) - Set-theoretic operators on intervals.

## Samplings

Samplings represent the way in which a function is to be sampled. They are used by the sample and histogram procedures.

- (make-sampling
*interval samples*)

(sampling*min max samples*) - Constructors

(sampling-interval*sampling*)

(sampling-samples*sampling*)

(sampling-min*sampling*)

(sampling-max*sampling*)- Accessors
- (sampling-step
*sampling*) - (sampling-interval-size
*sampling*) - Derived attributes of samplings.
- (value->sampling-index
*value sampling*) - (sampling-index->value
*index sampling*) - Convert between values in the sampled interval and indicies (buckets) to which they map under the sampling.

- (one-shot
*input*) - (one-shot
*input pulse-width*) - (one-shot
*input pulse-width pulse-spacing*) - When called with one argument, outputs true for one clock cycle whenever
*input*transitions from false to true, otherwise outputs false. When called with two arguments, the output is true for*pulse-width*milliseconds each time the*input*transitions from false to true. When called with three arguments, the transducer stops monitoring the input for*pulse-spacing*milliseconds after each rising edge . - (integral
*input normalizer*) - Returns the time integral of
*input*divided by*normalizer*. The*normalizer*is provided because*girl*measures time in milliseconds. Thus the integral of 1 over 1 second is 1000,**not**1. The default value of*normalizer*is 1000.0. - (derivative
*input prescale*) - Returns the time derivative of
*input*multiplied by*prescale*. The*prescale*is provided because*girl*measures time in milliseconds. If the clock cycle is 100ms and the input changes from 0 to 100 in one clock cycle, then the derivative will be (100-0)/100 = 1,**not**1000 as it would be if the unit of time was a second. The default value of*prescale*is 1000.0. - (sum
*input*) - Returns the temporal sum of
*input*. It is like integral, but successive updates to the sum are not adjusted for the clock period. - (delta
*input*) - Returns the temporal difference of
*input*- the difference between the current value of*input*and the value of the previous clock cycle. It is therefore like derivative, but its output is not adjusted for clock period. - (hysteresis-threshold
*input low-threshold high-threshold*) - Thresholds
*input*. The output is #t if*input*is above*high-threshold*. However, the output will remain #t until*input*falls below*low-threshold*. It then remains #f until the input rises above*high-threshold*again. - (true-time
*input*) - Returns the number of milliseconds for which
*input*has been true. If the input is false, it returns 0. - (onset
*input*) - True whenever
*input*has just become true. Equivalent to (one-shot*input*), however onset is implemented as a modality, so multiple uses of onset on the same argument return the same actual signal. - (termination
*input*) - True whenever
*input*has just become false. Equivalent to (one-shot (not*input*)), however termination is implemented as a modality, so multiple uses of termination on the same argument return the same actual signal. - clock-frequency
- The target update-rate for the main control loop.
- measured-clock-frequency
- The actual measured update-rate for last cycle of the main control loop.

- (latch
*input control*) - Like a D flip-flip or a sample-and-hold device. Returns the value of
*input*from the last time that*control*was true. That is, whenever*control*true, it saves the current value of*input*. It outputs the last saved value. - (flip-flop
*set clear &key break-ties initial-value*) - Roughly like a JK flip-flop. Whenver the input
*set*is active, the output changes to true, whenever*clear*is active, it changes to false. When both are false, the output remains unchanged. When both are true, the output goes true, however, this can be changed by setting the break-ties keyword parameter to #f. The signal is initially false, unless changed with the initial-value keyword parameter. - (toggle
*control &optional initial-value*) - Output alternates between #t and #f each time
*control*is true. The default initial value is #f. - (latch-runs
*input min-run-length*) - Outputs the value of the last run of at least
*min-run-length*identical values in the*input*. Arguably,*min-run-length*should have been specified in milliseconds rather than clock ticks.

- (low-pass-filter
*input**half-life*) - A first-order causal low-pass-filter. Note that
*half-life*must be a constant. - (median3
*a b c*) - Returns the median of
*a*,*b*, and*c*. - (temporal-median3
*input*) - Returns the median of the last three samples of
*input*. - (clip
*input low-threshold high-threshold*)

(clamp*input low-threshold high-threshold*) (deprecated) - Returns
*input*, unless it goes outside of the range [*low-threshold, high-threshold*]. If*input*falls under*low-threshold*, clip returns*low-theshold*. If it rises above*high-threshold*, clip returns*high-threshold*. Note that the name "clamp" is now deprecated. - (saturate
*input level*) - Equivalent to (clip
*input*(-*level*)*level*). - (suppress-weak
*input threshold*) - The opposite of saturate. Returns:
*input*, if its absolute value is over*threshold*,- 0, otherwise.

- (dead-zone
*input threshold*) - The standard control-theoretic dead-zone. Output is:
- 0, if the absolute value of
*input*is under*threshold*, *input*-*threshold*, if*input*is over*threshold*, and*input*+*threshold*, if*input*is less than -*threshold*.

- 0, if the absolute value of

Angles should really be their own data types, but for the moment, they're just
represented as numbers. That means you need to use special operations to normalize
them into cannonical ranges (assuming you want to). The standard library provides
normalization operations for angles represented in radians and degress. Angles can
be normalized into *signed* values or *unsigned* values. Signed angles
range from -p to +p radians (-180 to
+180 degrees), while unsigned angles range from 0 to 2p radians
(0 to 360 degrees).

- (normalize-degrees
*degrees*) - (normalize-radians
*radians*) - (signed-normalize-degrees
*degrees*) - (signed-normalize-radians
*radians*) - Maps an angle to its canonical signed or unsigned range.

(sign-extend-degrees*degrees*)- (sign-extend-radians
*radians*) - Maps a canonical unsigned angle to its canonical signed version. These are special cases of signed-normalize-X for angles that are already normalized as unsigned numbers.

(degrees->radians*degrees*)- (radians->degrees
*radians*) - Unit conversion.

(subtract-angles-degrees*angle1 angle2*)- (subtract-angles-radians
*angle1 angle2*) - Subtracts
*angle2*from*angle1*and then normalizes the result as a signed angle.

pi- twopi
- The obvious constants.

- (reduce-signals
*proc list*) *Proc*should be a procedure, signal procedure, or transducer and*list*should be a list of signals. Returns the result of recursively applying*proc*pairwise to all the elements of*list*.- (delay
*input**time*) - Returns a version of
*input*that has been delayed by approximately*time*milliseconds. - (count
*step? reset?*)

(counter*step? reset?*) - Counts upward each time
*step?*is true. Resets to zero when*reset?*is true. Note that the name "counter" is now deprecated. - (median3
*a b c*) - Returns the median (middle value) of the three values.
- (temporal-median3
*signal*) - Returns the median (middle value) of the last three values of the signal.
- (square
*number*) - Returns the square of
*number*. - (sgn
*input*) - Returns +1 if
*input*is positive, -1 if*input is negative*, or else 0. - (pd-controller
*input p-gain d-gain*) - A standard proportional-derivative controller.

Vector operations come in several different flavors. The naming conventions are as follows:

- vector-
x- Performs the
xoperation on a vector. The argument is a vector.- vector-
x-region- Performs the
xoperation on a segment of the vector. The argument is a vector, the index of the starting element of the segment, and the length of the segment.- vector-
x-region-circular- Performs the
xoperation on a segment of the vector. The argument is a vector, the index of the starting element of the segment, and the length of the segment. However, if the segment extends past the end of the vector, it wraps around to the beginning.

Most of the region version are now made redundant by the primitives for extracting regions from vectors. However, they are maintained for backward compatibility and (arguably) for convenience.

- (vector-reduce
*proc init vector*)

(vector-reduce-region*proc init vector start length*)

(vector-reduce-region-circular*proc init vector start length*) - Analogous to reduce or reduce-signals.
Computes the result of applying
*proc*to*init*and each successive element of*vector*. Note that*proc*must be a primitive procedure, not a signal procedure or a transducer. - (prefix-scan
*proc init vector*) - (prefix-backscan
*proc init vector*) - Like vector-reduce, but returns a vector containing the reductions of all the prefixes
(or suffixes) of the input vector. Thus (prefix-scan + 0
*v*) returns a vector of the same length and element type as*v*whose*i*th element is the sum of the first*i*elements of*v*. Prefix-backscan is the same except it works backward through the vector, so it returns a vector of reductions over*suffixes*of the array, rather than of prefixes. - (vector-min
*vector*)

(vector-min-region*vector start length*)

(vector-min-region-circular*vector start length*) - Returns the minium value of the selected vector or region.
- (vector-max
*vector*)

(vector-max-region*vector start length*)

(vector-max-region-circular*vector start length*) - Returns the maximum value of the selected vector or region.
- (gated-vector-min
*vector predicate-vector default*)

(gated-vector-max*vector predicate-vector default*) - Returns the minumum (maximum) of all the elements of
*vector*for which the corresponding position in the vector*predicate-vector*is true, or*default*, whichever is smaller (or larger, respectively). - (vector-arg-min
*vector*)

(vector-arg-min-region*vector start length*) - Returns the
*index*of the minium value of the selected vector or region. - (vector-arg-max
*vector*)

(vector-arg-max-region*vector start length*) - Returns the
*index*of the maximum value of the selected vector or region. - (vector-min->group
*vector*)

(vector-max->group*vector*) - Returns
*both*the minimum/maximum value of the vector and its index. The result is returned as a group with components index and min (or max). - (vector-centroid
*vector*)

(vector-centroid-region*vector start length*)

(vector-centroid-region-circular*vector start length*) - Computes the centroid of the vector (or vector region), i.e. the sum of
*vector*[*i*]**i*divided by the length of the vector (or region). - (dot-product
*vector1 vector2*) - Returns the sum of the products of the elements of the two vectors.

- (vector-range
*vector*) - Returns the range of elements spanned by
*vector*, represented as an interval. - (vector-region
*vector start length*) - (vector-region-circular
*vector start length*) - Returns the subvector of
*vector*starting with element*start*and running for*length*elements.

- (sample
*function sampling*) - (sample
*function min-arg max-arg sample-count*) - Samples the function
*function*, which may be a primitive procedure or a signal procedure, and returns the samples as a vector. The procedure takes*sample-count*samples from*min-arg*to*max-arg*. - (histogram
*vector sampling*) - Returns a histogram of the values of
*vector*, as divided into buckets by*sampling*. - (histogram-nth-median
*histogram n*) - Returns a number such that
*n*% of the values in the histogram are less than that number.

- (sequence
*reset? first-output*(*condition? next-output*) ...) - Returns a signal that begins with
*first-output*, then moves on to each*next-output*as their respective*condition?*s become true. Returns to*first-output*when*reset?*is true. - (trt-sequence
*first-output*(*condition? next-output*) ...) - Always outputs the leftmost output whose associated
*condition?*is false. Thus, it is like a sequence that can move backward when one of the*condition?*s becomes false.