Go forward to Vector and Matrix Arithmetic. Go backward to Extracting Elements. Go up to Matrix Functions.

Manipulating Vectors
====================

The `v l' (`calc-vlength') [`vlen'] command computes the length of a
vector.  The length of a non-vector is considered to be zero.  Note
that matrices are just vectors of vectors for the purposes of this
command.

With the Hyperbolic flag, `H v l' [`mdims'] computes a vector of the
dimensions of a vector, matrix, or higher-order object.  For example,
`mdims([[a,b,c],[d,e,f]])' returns `[2, 3]' since its argument is a
2x3 matrix.

The `v f' (`calc-vector-find') [`find'] command searches along a
vector for the first element equal to a given target.  The target is
on the top of the stack; the vector is in the second-to-top position.
If a match is found, the result is the index of the matching element.
Otherwise, the result is zero.  The numeric prefix argument, if given,
allows you to select any starting index for the search.

The `v a' (`calc-arrange-vector') [`arrange'] command
rearranges a vector to have a certain number of columns and rows.  The
numeric prefix argument specifies the number of columns; if you do not
provide an argument, you will be prompted for the number of columns.
The vector or matrix on the top of the stack is "flattened" into a
plain vector.  If the number of columns is nonzero, this vector is
then formed into a matrix by taking successive groups of N elements.
If the number of columns does not evenly divide the number of elements
in the vector, the last row will be short and the result will not be
suitable for use as a matrix.  For example, with the matrix
`[[1, 2], [3, 4]]' on the stack, `v a 4' produces
`[[1, 2, 3, 4]]' (a 1x4 matrix), `v a 1' produces
`[[1], [2], [3], [4]]' (a 4x1 matrix), `v a 2' produces
`[[1, 2], [3, 4]]' (the original 2x2 matrix), `v a 3' produces
`[[1, 2, 3], [4]]' (not a matrix), and `v a 0' produces
the flattened list `[1, 2, 3, 4]'.

The `V S' (`calc-sort') [`sort'] command sorts the elements of a
vector into increasing order.  Real numbers, real infinities, and
constant interval forms come first in this ordering; next come other
kinds of numbers, then variables (in alphabetical order), then finally
come formulas and other kinds of objects; these are sorted according
to a kind of lexicographic ordering with the useful property that one
vector is less or greater than another if the first corresponding
unequal elements are less or greater, respectively.  Since quoted
strings are stored by Calc internally as vectors of ASCII character
codes (See Strings), this means vectors of strings are also sorted
into alphabetical order by this command.

The `I V S' [`rsort'] command sorts a vector into decreasing order.

The `V G' (`calc-grade') [`grade', `rgrade'] command produces an index
table or permutation vector which, if applied to the input vector (as
the index of `C-u v r', say), would sort the vector.  A permutation
vector is just a vector of integers from 1 to N, where each integer
occurs exactly once.  One application of this is to sort a matrix of
data rows using one column as the sort key; extract that column, grade
it with `V G', then use the result to reorder the original matrix with
`C-u v r'.  Another interesting property of the `V G' command is that,
if the input is itself a permutation vector, the result will be the
inverse of the permutation.  The inverse of an index table is a rank
table, whose Kth element says where the Kth original vector element
will rest when the vector is sorted.  To get a rank table, just use `V
G V G'.

With the Inverse flag, `I V G' produces an index table that would sort
the input into decreasing order.  Note that `V S' and `V G' use a
"stable" sorting algorithm, i.e., any two elements which are equal
will not be moved out of their original order.  Generally there is no
way to tell with `V S', since two elements which are equal look the
same, but with `V G' this can be an important issue.  In the
matrix-of-rows example, suppose you have names and telephone numbers
as two columns and you wish to sort by phone number primarily, and by
name when the numbers are equal.  You can sort the data matrix by
names first, and then again by phone numbers.  Because the sort is
stable, any two rows with equal phone numbers will remain sorted by
name even after the second sort.

The `V H' (`calc-histogram') [`histogram'] command builds a histogram
of a vector of numbers.  Vector elements are assumed to be integers or
real numbers in the range [0..N) for some "number of bins" N, which is
the numeric prefix argument given to the command.  The result is a
vector of N counts of how many times each value appeared in the
original vector.  Non-integers in the input are rounded down to
integers.  Any vector elements outside the specified range are
ignored.  (You can tell if elements have been ignored by noting that
the counts in the result vector don't add up to the length of the
input vector.)

With the Hyperbolic flag, `H V H' pulls two vectors from the stack.
The second-to-top vector is the list of numbers as before.  The top
vector is an equal-sized list of "weights" to attach to the elements
of the data vector.  For example, if the first data element is 4.2 and
the first weight is 10, then 10 will be added to bin 4 of the result
vector.  Without the hyperbolic flag, every element has a weight of
one.

The `v t' (`calc-transpose') [`trn'] command computes the transpose of
the matrix at the top of the stack.  If the argument is a plain
vector, it is treated as a row vector and transposed into a one-column
matrix.

The `v v' (`calc-reverse-vector') [`vec'] command reverses a vector
end-for-end.  Given a matrix, it reverses the order of the rows.  (To
reverse the columns instead, just use `v t v v v t'.  The same
principle can be used to apply other vector commands to the columns of
a matrix.)

The `v m' (`calc-mask-vector') [`vmask'] command uses
one vector as a mask to extract elements of another vector.  The mask
is in the second-to-top position; the target vector is on the top of
the stack.  These vectors must have the same length.  The result is
the same as the target vector, but with all elements which correspond
to zeros in the mask vector deleted.  Thus, for example,
`vmask([1, 0, 1, 0, 1], [a, b, c, d, e])' produces `[a, c, e]'.
See Logical Operations.

The `v e' (`calc-expand-vector') [`vexp'] command expands a vector
according to another mask vector.  The result is a vector the same
length as the mask, but with nonzero elements replaced by successive
elements from the target vector.  The length of the target vector is
normally the number of nonzero elements in the mask.  If the target
vector is longer, its last few elements are lost.  If the target
vector is shorter, the last few nonzero mask elements are left
unreplaced in the result.  Thus `vexp([2, 0, 3, 0, 7], [a, b])'
produces `[a, 0, b, 0, 7]'.

With the Hyperbolic flag, `H v e' takes a filler value from the top of
the stack; the mask and target vectors come from the third and second
elements of the stack.  This filler is used where the mask is zero:
`vexp([2, 0, 3, 0, 7], [a, b], z)' produces `[a, z, c, z, 7]'.  If the
filler value is itself a vector, then successive values are taken from
it, so that the effect is to interleave two vectors according to the
mask: `vexp([2, 0, 3, 7, 0, 0], [a, b], [x, y])' produces `[a, x, b,
7, y, 0]'.

Another variation on the masking idea is to combine `[a, b, c, d, e]'
with the mask `[1, 0, 1, 0, 1]' to produce `[a, 0, c, 0, e]'.  You can
accomplish this with `V M a &', mapping the logical "and" operation
across the two vectors.  See Logical Operations.  Note that the `? 
:' operation also discussed there allows other types of masking using
vectors.