Next: Building Vectors, Previous: Matrix Functions, Up: Matrix Functions

Calc's “pack” and “unpack” commands collect stack entries to build composite objects such as vectors and complex numbers. They are described in this chapter because they are most often used to build vectors.

The `v p` (`calc-pack`

) [`pack`

] command collects several
elements from the stack into a matrix, complex number, HMS form, error
form, etc. It uses a numeric prefix argument to specify the kind of
object to be built; this argument is referred to as the “packing mode.”
If the packing mode is a nonnegative integer, a vector of that
length is created. For example, `C-u 5 v p` will pop the top
five stack elements and push back a single vector of those five
elements. (`C-u 0 v p` simply creates an empty vector.)

The same effect can be had by pressing `[` to push an incomplete
vector on the stack, using <TAB> (`calc-roll-down`

) to sneak
the incomplete object up past a certain number of elements, and
then pressing `]` to complete the vector.

Negative packing modes create other kinds of composite objects:

- -1
- Two values are collected to build a complex number. For example,
`5 <RET> 7 C-u -1 v p`creates the complex number ‘`(5, 7)`’. The result is always a rectangular complex number. The two input values must both be real numbers, i.e., integers, fractions, or floats. If they are not, Calc will instead build a formula like ‘`a + (0, 1) b`’. (The other packing modes also create a symbolic answer if the components are not suitable.) - -2
- Two values are collected to build a polar complex number.
The first is the magnitude; the second is the phase expressed
in either degrees or radians according to the current angular
mode.
- -3
- Three values are collected into an HMS form. The first
two values (hours and minutes) must be integers or
integer-valued floats. The third value may be any real
number.
- -4
- Two values are collected into an error form. The inputs
may be real numbers or formulas.
- -5
- Two values are collected into a modulo form. The inputs
must be real numbers.
- -6
- Two values are collected into the interval ‘
`[a .. b]`’. The inputs may be real numbers, HMS or date forms, or formulas. - -7
- Two values are collected into the interval ‘
`[a .. b)`’. - -8
- Two values are collected into the interval ‘
`(a .. b]`’. - -9
- Two values are collected into the interval ‘
`(a .. b)`’. - -10
- Two integer values are collected into a fraction.
- -11
- Two values are collected into a floating-point number.
The first is the mantissa; the second, which must be an
integer, is the exponent. The result is the mantissa
times ten to the power of the exponent.
- -12
- This is treated the same as
*-11*by the`v p`command. When unpacking,*-12*specifies that a floating-point mantissa is desired. - -13
- A real number is converted into a date form.
- -14
- Three numbers (year, month, day) are packed into a pure date form.
- -15
- Six numbers are packed into a date/time form.

With any of the two-input negative packing modes, either or both
of the inputs may be vectors. If both are vectors of the same
length, the result is another vector made by packing corresponding
elements of the input vectors. If one input is a vector and the
other is a plain number, the number is packed along with each vector
element to produce a new vector. For example, `C-u -4 v p`
could be used to convert a vector of numbers and a vector of errors
into a single vector of error forms; `C-u -5 v p` could convert
a vector of numbers and a single number `M` into a vector of
numbers modulo `M`.

If you don't give a prefix argument to `v p`, it takes
the packing mode from the top of the stack. The elements to
be packed then begin at stack level 2. Thus
`1 <RET> 2 <RET> 4 n v p` is another way to
enter the error form ‘`1 +/- 2`’.

If the packing mode taken from the stack is a vector, the result is a
matrix with the dimensions specified by the elements of the vector,
which must each be integers. For example, if the packing mode is
‘`[2, 3]`’, then six numbers will be taken from the stack and
returned in the form ‘`[[a, b, c], [d, e, f]]`’.

If any elements of the vector are negative, other kinds of
packing are done at that level as described above. For
example, ‘`[2, 3, -4]`’ takes 12 objects and creates a
2x3
matrix of error forms: ‘`[[a +/- b, c +/- d ... ]]`’.
Also, ‘`[-4, -10]`’ will convert four integers into an
error form consisting of two fractions: ‘`a:b +/- c:d`’.

There is an equivalent algebraic function,
‘`pack( mode, items)`’ where

The `v u` (`calc-unpack`

) command takes the vector, complex
number, HMS form, or other composite object on the top of the stack and
“unpacks” it, pushing each of its elements onto the stack as separate
objects. Thus, it is the “inverse” of `v p`. If the value
at the top of the stack is a formula, `v u` unpacks it by pushing
each of the arguments of the top-level operator onto the stack.

You can optionally give a numeric prefix argument to `v u`
to specify an explicit (un)packing mode. If the packing mode is
negative and the input is actually a vector or matrix, the result
will be two or more similar vectors or matrices of the elements.
For example, given the vector ‘`[a +/- b, c^2, d +/- 7]`’,
the result of `C-u -4 v u` will be the two vectors
‘`[a, c^2, d]`’ and ‘`[b, 0, 7]`’.

Note that the prefix argument can have an effect even when the input is
not a vector. For example, if the input is the number *-5*, then
`c-u -1 v u` yields *-5* and 0 (the components of *-5*
when viewed as a rectangular complex number); `C-u -2 v u` yields 5
and 180 (assuming Degrees mode); and `C-u -10 v u` yields *-5*
and 1 (the numerator and denominator of *-5*, viewed as a rational
number). Plain `v u` with this input would complain that the input
is not a composite object.

Unpacking mode *-11* converts a float into an integer mantissa and
an integer exponent, where the mantissa is not divisible by 10
(except that 0.0 is represented by a mantissa and exponent of 0).
Unpacking mode *-12* converts a float into a floating-point mantissa
and integer exponent, where the mantissa (for non-zero numbers)
is guaranteed to lie in the range [1 .. 10). In both cases,
the mantissa is shifted left or right (and the exponent adjusted
to compensate) in order to satisfy these constraints.

Positive unpacking modes are treated differently than for `v p`.
A mode of 1 is much like plain `v u` with no prefix argument,
except that in addition to the components of the input object,
a suitable packing mode to re-pack the object is also pushed.
Thus, `C-u 1 v u` followed by `v p` will re-build the
original object.

A mode of 2 unpacks two levels of the object; the resulting re-packing mode will be a vector of length 2. This might be used to unpack a matrix, say, or a vector of error forms. Higher unpacking modes unpack the input even more deeply.

There are two algebraic functions analogous to `v u`.
The ‘`unpack( mode, item)`’ function unpacks the

The `unpackt`

function is like `unpack`

but instead
of returning a simple vector of items, it returns a vector of
two things: The mode, and the vector of items. For example,
‘`unpackt(1, 2:3 +/- 1:4)`’ returns ‘`[-4, [2:3, 1:4]]`’,
and ‘`unpackt(2, 2:3 +/- 1:4)`’ returns ‘`[[-4, -10], [2, 3, 1, 4]]`’.
The identity for re-building the original object is
‘`apply(pack, unpackt( n, x)) = x`’. (The

`apply`

function builds a function call given the function
name and a vector of arguments.)
Subscript notation is a useful way to extract a particular part
of an object. For example, to get the numerator of a rational
number, you can use ‘`unpack(-10, x)_1`’.