trusty (3) blt::vector.3.gz

Provided by: blt-dev_2.4z-7ubuntu2_amd64 bug

NAME

       vector -  Vector data type for Tcl

SYNOPSIS

       vector create vecName ?vecName...? ?switches?

       vector destroy vecName ?vecName...?

       vector expr expression

       vector names ?pattern...?
_________________________________________________________________

DESCRIPTION

       The vector command creates a vector of floating point values.  The vector's components can be manipulated
       in three ways: through a Tcl array variable, a Tcl command, or the C API.

INTRODUCTION

       A vector is simply an ordered set of numbers.  The components of a vector are real  numbers,  indexed  by
       counting numbers.

       Vectors  are  common  data structures for many applications.  For example, a graph may use two vectors to
       represent the X-Y coordinates of the data plotted.  The graph will  automatically  be  redrawn  when  the
       vectors  are  updated or changed. By using vectors, you can separate data analysis from the graph widget.
       This makes it easier, for example, to add data transformations, such as splines.  It's possible  to  plot
       the same data to in multiple graphs, where each graph presents a different view or scale of the data.

       You  could  try  to use Tcl's associative arrays as vectors.  Tcl arrays are easy to use.  You can access
       individual elements randomly by specifying the index, or the set the entire array by providing a list  of
       index  and  value  pairs for each element.  The disadvantages of associative arrays as vectors lie in the
       fact they are implemented as hash tables.

       • There's no implied ordering to the associative arrays.  If you used vectors  for  plotting,  you  would
         want  to insure the second component comes after the first, an so on.  This isn't possible since arrays
         are actually hash tables.  For example, you can't get a range of values between two indices.   Nor  can
         you sort an array.

       • Arrays  consume  lots of memory when the number of elements becomes large (tens of thousands).  This is
         because each element's index and value are stored as strings in the hash table.

       • The C programming interface is unwieldy.  Normally with vectors, you would like to view the  Tcl  array
         as you do a C array, as an array of floats or doubles.  But with hash tables, you must convert both the
         index and value to and from decimal strings, just to access an element in the  array.   This  makes  it
         cumbersome to perform operations on the array as a whole.

       The  vector  command  tries  to overcome these disadvantages while still retaining the ease of use of Tcl
       arrays.  The vector command creates both a new Tcl command and associate array which are  linked  to  the
       vector components.  You can randomly access vector components though the elements of array.  Not have all
       indices are generated for the array, so printing the array (using the parray procedure)  does  not  print
       out all the component values.  You can use the Tcl command to access the array as a whole.  You can copy,
       append, or sort vector using its command.  If you need greater performance, or customized  behavior,  you
       can write your own C code to manage vectors.

EXAMPLE

       You create vectors using the vector command and its create operation.

              # Create a new vector.
              vector create y(50)

       This  creates  a  new  vector  named  y.   It  has  fifty components, by default, initialized to 0.0.  In
       addition, both a Tcl command and array variable, both named y, are  created.   You  can  use  either  the
       command or variable to query or modify components of the vector.

              # Set the first value.
              set y(0) 9.25
              puts "y has [y length] components"

       The  array  y  can  be  used  to  read or set individual components of the vector.  Vector components are
       indexed from zero.  The array index must be a number less than the number of  components.   For  example,
       it's an error if you try to set the 51st element of y.

              # This is an error. The vector only has 50 components.
              set y(50) 0.02

       You  can  also specify a range of indices using a colon (:) to separate the first and last indices of the
       range.

              # Set the first six components of y
              set y(0:5) 25.2

       If you don't include an index, then it will default to the first and/or last component of the vector.

              # Print out all the components of y
              puts "y = $y(:)"

       There are special non-numeric indices.  The index end, specifies the last component of the vector.   It's
       an  error  to  use  this  index  if the vector is empty (length is zero).  The index ++end can be used to
       extend the vector by one component and initialize it to a specific value.  You can't read from the  array
       using this index, though.

              # Extend the vector by one component.
              set y(++end) 0.02

       The  other  special  indices are min and max.  They return the current smallest and largest components of
       the vector.

              # Print the bounds of the vector
              puts "min=$y(min) max=$y(max)"

       To delete components from a vector, simply unset  the  corresponding  array  element.  In  the  following
       example,  the  first  component of y is deleted.  All the remaining components of y will be moved down by
       one index as the length of the vector is reduced by one.

              # Delete the first component
              unset y(0)
              puts "new first element is $y(0)"

       The vector's Tcl command can also be used to query or set the vector.

              # Create and set the components of a new vector
              vector create x
              x set { 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 }

       Here we've created a vector x without a initial length specification.  In this case, the length is  zero.
       The set operation resets the vector, extending it and setting values for each new component.

       There  are  several operations for vectors.  The range operation lists the components of a vector between
       two indices.

              # List the components
              puts "x = [x range 0 end]"

       You can search for a particular value using the search operation.  It returns a list of  indices  of  the
       components with the same value.  If no component has the same value, it returns "".

              # Find the index of the biggest component
              set indices [x search $x(max)]

       Other  operations  copy,  append, or sort vectors.  You can append vectors or new values onto an existing
       vector with the append operation.

              # Append assorted vectors and values to x
              x append x2 x3 { 2.3 4.5 } x4

       The sort operation sorts the vector.  If any additional vectors are specified, they are rearranged in the
       same  order  as  the  vector.   For  example, you could use it to sort data points represented by x and y
       vectors.

              # Sort the data points
              x sort y

       The vector x is sorted while the components of y are rearranged so that the original x,y coordinate pairs
       are retained.

       The expr operation lets you perform arithmetic on vectors.  The result is stored in the vector.

              # Add the two vectors and a scalar
              x expr { x + y }
              x expr { x * 2 }

       When  a  vector  is modified, resized, or deleted, it may trigger call-backs to notify the clients of the
       vector.  For example, when a vector used in  the  graph  widget  is  updated,  the  vector  automatically
       notifies  the  widget that it has changed.  The graph can then redrawn itself at the next idle point.  By
       default, the notification occurs when Tk is next idle.  This way you can modify  the  vector  many  times
       without  incurring  the  penalty  of  the  graph  redrawing  itself for each change.  You can change this
       behavior using the notify operation.

              # Make vector x notify after every change
              x notify always
                ...
              # Never notify
              x notify never
                ...
              # Force notification now
              x notify now

       To delete a vector, use the vector delete command.  Both the vector and its corresponding Tcl command are
       destroyed.

              # Remove vector x
              vector destroy x

SYNTAX

       Vectors  are  created  using  the  vector create operation.  Th create operation can be invoked in one of
       three forms:

       vector create vecName
              This creates a new vector vecName which initially has no components.

       vector create vecName(size)
              This second form creates a  new  vector  which  will  contain  size  number  of  components.   The
              components will be indexed starting from zero (0). The default value for the components is 0.0.

       vector create vecName(first:last)
              The  last  form  creates  a  new  vector of indexed first through last.  First and last can be any
              integer value so long as first is less than last.

       Vector names must start with a letter and consist of letters, digits, or underscores.

              # Error: must start with letter
              vector create 1abc

       You can automatically generate vector names using the "#auto" vector name.   The  create  operation  will
       generate a unique vector name.

              set vec [vector create #auto]
              puts "$vec has [$vec length] components"

   VECTOR INDICES
       Vectors  are indexed by integers.  You can access the individual vector components via its array variable
       or Tcl command.  The string representing the index can be an integer, a numeric expression, a range, or a
       special keyword.

       The  index  must  lie  within the current range of the vector, otherwise an an error message is returned.
       Normally the indices of a vector are start from 0.  But you can use the  offset  operation  to  change  a
       vector's indices on-the-fly.

              puts $vecName(0)
              vecName offset -5
              puts $vecName(-5)

       You can also use numeric expressions as indices.  The result of the expression must be an integer value.

              set n 21
              set vecName($n+3) 50.2

       The following special non-numeric indices are available: min, max, end, and ++end.

              puts "min = $vecName($min)"
              set vecName(end) -1.2

       The  indices min and max will return the minimum and maximum values of the vector.  The index end returns
       the value of the last component in the vector.  The index ++end is used to  append  new  value  onto  the
       vector.  It automatically extends the vector by one component and sets its value.

              # Append an new component to the end
              set vecName(++end) 3.2

       A range of indices can be indicated by a colon (:).

              # Set the first six components to 1.0
              set vecName(0:5) 1.0

       If no index is supplied the first or last component is assumed.

              # Print the values of all the components
              puts $vecName(:)

VECTOR OPERATIONS

       vector create vecName?(size)?... ?switches?
              The  create operation creates a new vector vecName.  Both a Tcl command and array variable vecName
              are also created.  The name vecName must be unique, so another Tcl command or array  variable  can
              not  already exist in that scope.  You can access the components of the vector using its variable.
              If you change a value in the array, or unset an array element, the vector is  updated  to  reflect
              the  changes.   When  the  variable  vecName  is  unset,  the  vector and its Tcl command are also
              destroyed.

              The vector has optional switches that affect how the vector is created. They are as follows:

              -variable varName
                     Specifies the name of a Tcl variable to be mapped to the vector. If  the  variable  already
                     exists,  it  is  first  deleted,  then  recreated.  If varName is the empty string, then no
                     variable will be mapped.  You can always map a  variable  back  to  the  vector  using  the
                     vector's variable operation.

              -command cmdName
                     Maps  a  Tcl command to the vector. The vector can be accessed using cmdName and one of the
                     vector instance operations.  A Tcl command by that name cannot already exist.   If  cmdName
                     is the empty string, no command mapping will be made.

              -watchunset boolean
                     Indicates  that  the  vector  should automatically delete itself if the variable associated
                     with the vector is unset.  By default, the vector will not be deleted.  This  is  different
                     from previous releases.  Set boolean to "true" to get the old behavior.

       vector destroy vecName ?vecName...?

       vector expr expression
              All  binary operators take vectors as operands (remember that numbers are treated as one-component
              vectors).  The exact action of binary operators depends upon the length of the second operand.  If
              the  second  operand  has  only  one  component,  then each element of the first vector operand is
              computed by that value.  For example, the expression "x * 2" multiples all elements of the  vector
              x by 2.  If the second operand has more than one component, both operands must be the same length.
              Each pair of corresponding elements are computed.  So "x + y" adds the the first components  of  x
              and y together, the second, and so on.

              The valid operators are listed below, grouped in decreasing order of precedence:

              -  !                Unary minus and logical NOT.  The unary minus flips the sign of each component
                                  in the vector.  The logical not operator returns a vector of whose values  are
                                  0.0 or 1.0.  For each non-zero component 1.0 is returned, 0.0 otherwise.

              ^                   Exponentiation.

              *  /  %             Multiply, divide, remainder.

              +  -                Add and subtract.

              <<  >>              Left  and  right  shift.   Circularly  shifts  the  values  of the vector (not
                                  implemented yet).

              <  >  <=  >=        Boolean less, greater, less than or equal, and greater than  or  equal.   Each
                                  operator returns a vector of ones and zeros.  If the condition is true, 1.0 is
                                  the component value, 0.0 otherwise.

              ==  !=              Boolean equal and not equal.  Each operator  returns  a  vector  of  ones  and
                                  zeros.  If the condition is true, 1.0 is the component value, 0.0 otherwise.

              |                   Bit-wise OR.  (Not implemented).

              &&                  Logical AND.  Produces a 1 result if both operands are non-zero, 0 otherwise.

              ||                  Logical OR.  Produces a 0 result if both operands are zero, 1 otherwise.

              x?y:z               If-then-else, as in C.  (Not implemented yet).

              See  the  C  manual  for more details on the results produced by each operator.  All of the binary
              operators group left-to-right within the same precedence level.

              Several mathematical functions are supported for vectors.  Each of the following functions invokes
              the  math  library function of the same name; see the manual entries for the library functions for
              details on what they do.  The operation is applied to all elements of  the  vector  returning  the
              results.

                     acos        cos         hypot      sinh
                     asin        cosh        log        sqrt
                     atan        exp         log10      tan
                     ceil        floor       sin        tanh

              Additional functions are:

              abs       Returns the absolute value of each component.

              random    Returns  a  vector of non-negative values uniformly distributed between [0.0, 1.0) using
                        drand48.  The seed comes from the internal clock of the machine or  may  be  set  manual
                        with the srandom function.

              round     Rounds each component of the vector.

              srandom   Initializes  the  random number generator using srand48.  The high order 32-bits are set
                        using the integral portion of the first  vector  component.  All  other  components  are
                        ignored.  The low order 16-bits are set to an arbitrary value.

              The following functions return a single value.

              adev      Returns  the  average  deviation  (defined  as  the  sum  of  the absolute values of the
                        differences between component and the mean, divided by the length of the vector).

              kurtosis  Returns the degree of peakedness (fourth moment) of the vector.

              length    Returns the number of components in the vector.

              max       Returns the vector's maximum value.

              mean      Returns the mean value of the vector.

              median    Returns the median of the vector.

              min       Returns the vector's minimum value.

              q1        Returns the first quartile of the vector.

              q3        Returns the third quartile of the vector.

              prod      Returns the product of the components.

              sdev      Returns the standard deviation (defined as the square  root  of  the  variance)  of  the
                        vector.

              skew      Returns  the skewness (or third moment) of the vector.  This characterizes the degree of
                        asymmetry of the vector about the mean.

              sum       Returns the sum of the components.

              var       Returns the variance of the vector. The sum of  the  squared  differences  between  each
                        component  and  the  mean is computed.  The variance is the sum divided by the length of
                        the vector minus 1.

              The last set returns a vector of the same length as the argument.

              norm      Scales the values of the vector to lie in the range [0.0..1.0].

              sort      Returns the vector components sorted in ascending order.

       vector names ?pattern?

INSTANCE OPERATIONS

       You can also use the vector's Tcl command to query or modify it.  The general form is  vecName  operation
       ?arg?...   Both  operation and its arguments determine the exact behavior of the command.  The operations
       available for vectors are listed below.

       vecName append item ?item?...
              Appends the component values from item to vecName.  Item can be either the name of a vector  or  a
              list of numeric values.

       vecName binread channel ?length? ?switches?
              Reads  binary  values  from  a Tcl channel. Values are either appended to the end of the vector or
              placed at a given index (using the -at option), overwriting existing values.  Data is  read  until
              EOF is found on the channel or a specified number of values length are read (note that this is not
              necessarily the same as the number of bytes). The following switches are supported:

              -swap  Swap bytes and words.  The default endian is the host machine.

              -at index
                     New values will start at vector index index.  This will overwrite any current values.

              -format format
                     Specifies the format of the data.  Format can be one of the following:  "i1",  "i2",  "i4",
                     "i8",  "u1,  "u2",  "u4",  "u8",  "r4", "r8", or "r16".  The number indicates the number of
                     bytes required for each value.  The letter indicates the type:  "i"  for  signed,  "u"  for
                     unsigned, "r" or real.  The default format is "r16".

       vecName clear
              Clears  the  element indices from the array variable associated with vecName.  This doesn't affect
              the components of the vector.  By default, the number of entries in the Tcl  array  doesn't  match
              the  number  of  components  in the vector.  This is because its too expensive to maintain decimal
              strings for both the index and value for each component.  Instead, the index and value  are  saved
              only when you read or write an element with a new index.  This command removes the index and value
              strings from the array.  This is useful when the vector is large.

       vecName delete index ?index?...
              Deletes the indexth component from the vector vecName.  Index is the index of the  element  to  be
              deleted.  This is the same as unsetting the array variable element index.  The vector is compacted
              after all the indices have been deleted.

       vecName dup destName
              Copies vecName to destName. DestName is the name of a destination vector.  If  a  vector  destName
              already  exists,  it  is  overwritten  with  the components of vecName.  Otherwise a new vector is
              created.

       vecName expr expression
              Computes the expression and resets the values of the vector accordingly.  Both scalar  and  vector
              math  operations  are  allowed.   All  values  in  expressions are either real numbers or names of
              vectors.  All numbers are treated as one component vectors.

       vecName length ?newSize?
              Queries or resets the number of components in vecName.  NewSize is a  number  specifying  the  new
              size of the vector.  If newSize is smaller than the current size of vecName, vecName is truncated.
              If newSize is greater, the vector is extended and the new components are initialized to  0.0.   If
              no newSize argument is present, the current length of the vector is returned.

       vecName merge srcName ?srcName?...
              Merges  the  named  vectors  into  a single vector.  The resulting vector is formed by merging the
              components of each source vector one index at a time.

       vecName notify keyword
              Controls how vector clients are notified  of  changes  to  the  vector.   The  exact  behavior  is
              determined by keyword.

              always Indicates that clients are to be notified immediately whenever the vector is updated.

              never  Indicates that no clients are to be notified.

              whenidle
                     Indicates  that  clients  are  to be notified at the next idle point whenever the vector is
                     updated.

              now    If any client notifications is currently pending, they are notified immediately.

              cancel Cancels pending notifications of clients using the vector.

              pending
                     Returns 1 if a client notification is pending, and 0 otherwise.

       vecName offset ?value?
              Shifts the indices of the vector by the amount specified by value.  Value is  an  integer  number.
              If no value argument is given, the current offset is returned.

       vecName populate destName ?density?
              Creates  a  vector  destName  which  is  a  superset  of  vecName.   DestName will include all the
              components of vecName, in addition the interval between  each  of  the  original  components  will
              contain  a  density  number  of  new  components,  whose values are evenly distributed between the
              original components values.  This is useful for generating abscissas to be  interpolated  along  a
              spline.

       vecName range firstIndex ?lastIndex?...
              Returns  a  list  of  numeric  values representing the vector components between two indices. Both
              firstIndex and lastIndex are indices representing the range  of  components  to  be  returned.  If
              lastIndex is less than firstIndex, the components are listed in reverse order.

       vecName search value ?value?
              Searches for a value or range of values among the components of vecName.  If one value argument is
              given, a list of indices of the components which equal value is returned.  If a  second  value  is
              also provided, then the indices of all components which lie within the range of the two values are
              returned.  If no components are found, then "" is returned.

       vecName set item
              Resets the components of the vector to item. Item can be either a list of numeric  expressions  or
              another vector.

       vecName seq start ?finish? ?step?
              Generates  a  sequence  of values starting with the value start.  Finish indicates the terminating
              value of the sequence.  The vector is automatically resized to  contain  just  the  sequence.   If
              three arguments are present, step designates the interval.

              With  only  two  arguments  (no  finish  argument), the sequence will continue until the vector is
              filled.  With one argument, the interval defaults to 1.0.

       vecName sort ?-reverse? ?argName?...
              Sorts the vector vecName in increasing order.  If the -reverse flag  is  present,  the  vector  is
              sorted in decreasing order.  If other arguments argName are present, they are the names of vectors
              which will be rearranged in the same manner as vecName.  Each vector must be the  same  length  as
              vecName.   You  could use this to sort the x vector of a graph, while still retaining the same x,y
              coordinate pairs in a y vector.

       vecName variable varName
              Maps a Tcl variable to the vector, creating another means for accessing the vector.  The  variable
              varName can't already exist. This overrides any current variable mapping the vector may have.

C LANGUAGE API

       You can create, modify, and destroy vectors from C code, using library routines.  You need to include the
       header file blt.h. It contains the definition of the structure Blt_Vector, which represents  the  vector.
       It appears below.

              typedef struct {
                  double *valueArr;
                  int numValues;
                  int arraySize;
                  double min, max;
              } Blt_Vector;

       The field valueArr points to memory holding the vector components.  The components are stored in a double
       precision array, whose size size is represented by arraySize.  NumValues is the length  of  vector.   The
       size  of  the  array is always equal to or larger than the length of the vector.  Min and max are minimum
       and maximum component values.

LIBRARY ROUTINES

       The following routines are available from C to manage vectors.  Vectors  are  identified  by  the  vector
       name.

       Blt_CreateVector

         Synopsis:

                   int Blt_CreateVector (interp, vecName, length, vecPtrPtr)
                                Tcl_Interp *interp;
                                char *vecName;
                                int length;
                                Blt_Vector **vecPtrPtr;

         Description:
                   Creates  a  new  vector vecName with a length of length.  Blt_CreateVector creates both a new
                   Tcl command and array variable vecName.  Neither a command nor  variable  named  vecName  can
                   already exist.  A pointer to the vector is placed into vecPtrPtr.

         Results:  Returns  TCL_OK if the vector is successfully created.  If length is negative, a Tcl variable
                   or command vecName already exists, or  memory  cannot  be  allocated  for  the  vector,  then
                   TCL_ERROR is returned and interp->result will contain an error message.

       Blt_DeleteVectorByName

         Synopsis:

                   int Blt_DeleteVectorByName (interp, vecName)
                                Tcl_Interp *interp;
                                char *vecName;

         Description:
                   Removes  the vector vecName.  VecName is the name of a vector which must already exist.  Both
                   the Tcl command and array variable vecName are destroyed.  All clients of the vector will  be
                   notified immediately that the vector has been destroyed.

         Results:  Returns  TCL_OK  if the vector is successfully deleted.  If vecName is not the name a vector,
                   then TCL_ERROR is returned and interp->result will contain an error message.

       Blt_DeleteVector

         Synopsis:

                   int Blt_DeleteVector (vecPtr)
                                Blt_Vector *vecPtr;

         Description:
                   Removes the vector pointed to by vecPtr.  VecPtr is a pointer to a vector, typically  set  by
                   Blt_GetVector or Blt_CreateVector.  Both the Tcl command and array variable of the vector are
                   destroyed.  All clients of the vector will be notified immediately that the vector  has  been
                   destroyed.

         Results:  Returns  TCL_OK  if the vector is successfully deleted.  If vecName is not the name a vector,
                   then TCL_ERROR is returned and interp->result will contain an error message.

       Blt_GetVector

         Synopsis:

                   int Blt_GetVector (interp, vecName, vecPtrPtr)
                                Tcl_Interp *interp;
                                char *vecName;
                                Blt_Vector **vecPtrPtr;

         Description:
                   Retrieves the vector vecName.  VecName is the name of a  vector  which  must  already  exist.
                   VecPtrPtr will point be set to the address of the vector.

         Results:  Returns  TCL_OK  if  the  vector  is successfully retrieved.  If vecName is not the name of a
                   vector, then TCL_ERROR is returned and interp->result will contain an error message.

       Blt_ResetVector

         Synopsis:

                   int Blt_ResetVector (vecPtr, dataArr,
                     numValues, arraySize, freeProc)
                                Blt_Vector *vecPtr;
                                double *dataArr;
                                int *numValues;
                                int *arraySize;
                                Tcl_FreeProc *freeProc;

         Description:
                   Resets the components of the vector pointed  to  by  vecPtr.   Calling  Blt_ResetVector  will
                   trigger  the vector to dispatch notifications to its clients. DataArr is the array of doubles
                   which represents the vector data. NumValues is the number of elements in the array. ArraySize
                   is  the actual size of the array (the array may be bigger than the number of values stored in
                   it). FreeProc indicates how  the  storage  for  the  vector  component  array  (dataArr)  was
                   allocated.   It  is  used to determine how to reallocate memory when the vector is resized or
                   destroyed.  It must be TCL_DYNAMIC, TCL_STATIC, TCL_VOLATILE, or a pointer to a  function  to
                   free  the  memory  allocated  for the vector array. If freeProc is TCL_VOLATILE, it indicates
                   that dataArr must be copied and saved.  If freeProc is TCL_DYNAMIC, it indicates that dataArr
                   was  dynamically  allocated  and that Tcl should free dataArr if necessary.  Static indicates
                   that nothing should be done to release storage for dataArr.

         Results:  Returns TCL_OK if the vector is successfully resized.   If  newSize  is  negative,  a  vector
                   vecName  does  not  exist,  or  memory  cannot be allocated for the vector, then TCL_ERROR is
                   returned and interp->result will contain an error message.

       Blt_ResizeVector

         Synopsis:

                   int Blt_ResizeVector (vecPtr, newSize)
                                Blt_Vector *vecPtr;
                                int newSize;

         Description:
                   Resets the length of the vector pointed to by vecPtr to newSize.  If newSize is smaller  than
                   the  current  size  of  the  vector,  it  is truncated.  If newSize is greater, the vector is
                   extended and the new components are initialized to 0.0.  Calling Blt_ResetVector will trigger
                   the vector to dispatch notifications.

         Results:  Returns  TCL_OK  if the vector is successfully resized.  If newSize is negative or memory can
                   not be allocated for the vector, then TCL_ERROR is returned and interp->result  will  contain
                   an error message.

         Blt_VectorExists

            Synopsis:

                      int Blt_VectorExists (interp, vecName)
                                  Tcl_Interp *interp;
                                  char *vecName;

            Description:
                      Indicates if a vector named vecName exists in interp.

            Results:  Returns 1 if a vector vecName exists and 0 otherwise.

         If  your  application  needs  to  be  notified  when  a vector changes, it can allocate a unique client
         identifier for itself.  Using this identifier, you can then register a call-back to  be  made  whenever
         the  vector is updated or destroyed.  By default, the call-backs are made at the next idle point.  This
         can be changed to occur at the time the vector is modified.  An application can allocate more than  one
         identifier  for  any  vector.   When the client application is done with the vector, it should free the
         identifier.

         The call-back routine must of the following type.

                       typedef void (Blt_VectorChangedProc) (Tcl_Interp *interp,
                          ClientData clientData, Blt_VectorNotify notify);

         ClientData is passed to this routine whenever it is called.  You can use this to  pass  information  to
         the  call-back.   The notify argument indicates whether the vector has been updated of destroyed. It is
         an enumerated type.

                       typedef enum {
                           BLT_VECTOR_NOTIFY_UPDATE=1,
                           BLT_VECTOR_NOTIFY_DESTROY=2
                       } Blt_VectorNotify;

         Blt_AllocVectorId

            Synopsis:

                      Blt_VectorId Blt_AllocVectorId (interp, vecName)
                                  Tcl_Interp *interp;
                                  char *vecName;

            Description:
                      Allocates an client identifier for with the vector vecName.  This identifier can  be  used
                      to specify a call-back which is triggered when the vector is updated or destroyed.

            Results:  Returns  a  client identifier if successful.  If vecName is not the name of a vector, then
                      NULL is returned and interp->result will contain an error message.

         Blt_GetVectorById

            Synopsis:

                      int Blt_GetVector (interp, clientId, vecPtrPtr)
                                  Tcl_Interp *interp;
                                  Blt_VectorId clientId;
                                  Blt_Vector **vecPtrPtr;

            Description:
                      Retrieves the vector used by clientId.  ClientId  is  a  valid  vector  client  identifier
                      allocated by Blt_AllocVectorId.  VecPtrPtr will point be set to the address of the vector.

            Results:  Returns TCL_OK if the vector is successfully retrieved.

         Blt_SetVectorChangedProc

            Synopsis:

                      void Blt_SetVectorChangedProc (clientId, proc, clientData);
                                  Blt_VectorId clientId;
                                  Blt_VectorChangedProc *proc;
                                  ClientData *clientData;

            Description:
                      Specifies a call-back routine to be called whenever the vector associated with clientId is
                      updated or deleted.  Proc is a pointer to call-back  routine  and  must  be  of  the  type
                      Blt_VectorChangedProc.  ClientData is a one-word value to be passed to the routine when it
                      is invoked. If proc is NULL, then the client is not notified.

            Results:  The designated call-back  procedure  will  be  invoked  when  the  vector  is  updated  or
                      destroyed.

         Blt_FreeVectorId

            Synopsis:

                      void Blt_FreeVectorId (clientId);
                                  Blt_VectorId clientId;

            Description:
                      Frees the client identifier.  Memory allocated for the identifier is released.  The client
                      will no longer be notified when the vector is modified.

            Results:  The designated call-back procedure will be no longer be invoked when the vector is updated
                      or destroyed.

         Blt_NameOfVectorId

            Synopsis:

                      char *Blt_NameOfVectorId (clientId);
                                  Blt_VectorId clientId;

            Description:
                      Retrieves the name of the vector associated with the client identifier clientId.

            Results:  Returns the name of the vector associated with clientId.  If clientId is not an identifier
                      or the vector has been destroyed, NULL is returned.

         Blt_InstallIndexProc

            Synopsis:

                      void Blt_InstallIndexProc (indexName, procPtr)
                                  char *indexName;
                                  Blt_VectorIndexProc *procPtr;

            Description:
                      Registers a function to be called to retrieved the index indexName from the vector's array
                      variable.

                      typedef double Blt_VectorIndexProc(Vector *vecPtr);

                      The  function  will  be passed a pointer to the vector.  The function must return a double
                      representing the value at the index.

            Results:  The new index is installed into the vector.

C API EXAMPLE

       The following example opens a file of binary data and stores it in an array of doubles. The array size is
       computed  from the size of the file. If the vector "data" exists, calling Blt_VectorExists, Blt_GetVector
       is called to get the pointer to the vector.  Otherwise the routine Blt_CreateVector is called to create a
       new  vector  and  returns  a pointer to it. Just like the Tcl interface, both a new Tcl command and array
       variable are created when a new vector is created. It doesn't make any difference what the  initial  size
       of  the  vector  is  since it will be reset shortly. The vector is updated when lt_ResetVector is called.
       Blt_ResetVector makes the changes visible to the Tcl interface and other vector clients (such as a  graph
       widget).

              #include <tcl.h>
              #include <blt.h>
              ...
              Blt_Vector *vecPtr;
              double *newArr;
              FILE *f;
              struct stat statBuf;
              int numBytes, numValues;

              f = fopen("binary.dat", "r");
              fstat(fileno(f), &statBuf);
              numBytes = (int)statBuf.st_size;

              /* Allocate an array big enough to hold all the data */
              newArr = (double *)malloc(numBytes);
              numValues = numBytes / sizeof(double);
              fread((void *)newArr, numValues, sizeof(double), f);
              fclose(f);

              if (Blt_VectorExists(interp, "data"))  {
                  if (Blt_GetVector(interp, "data", &vecPtr) != TCL_OK) {
                return TCL_ERROR;
                  }
              } else {
                 if (Blt_CreateVector(interp, "data", 0, &vecPtr) != TCL_OK) {
                return TCL_ERROR;
                 }
              }
              /*
               * Reset the vector. Clients will be notified when Tk is idle.
               * TCL_DYNAMIC tells the vector to free the memory allocated
               * if it needs to reallocate or destroy the vector.
               */
              if (Blt_ResetVector(vecPtr, newArr, numValues, numValues,
                TCL_DYNAMIC) != TCL_OK) {
                  return TCL_ERROR;
              }

INCOMPATIBILITIES

       In  previous  versions, if the array variable isn't global (i.e. local to a Tcl procedure), the vector is
       automatically destroyed when the procedure returns.

              proc doit {} {
                  # Temporary vector x
                  vector x(10)
                  set x(9) 2.0
                    ...
              }

       This has changed.  Variables are not automatically destroyed when  their  variable  is  unset.   You  can
       restore the old behavior by setting the "-watchunset" switch.

KEYWORDS

       vector, graph, widget