vector command¶
The ::rbc::vector command creates and manages real or complex numeric vectors.
A vector can be accessed through:
its vector instance command
an associated Tcl array variable
the RBC C API.
Read-only vectors¶
Since 0.8.1, vectors can be protected against accidental data modification:
samples set {1 2 3}
samples readonly true
set result [rbc::vector expr -name #auto {samples * 2}]
samples readonly false
New vectors are writable by default. The state protects values, length and index offset; numeric type
remains immutable independently. Reads, statistics, arithmetic that returns a list, expressions using
the vector as input, and graph bindings remain available. Copies and newly created expression results
are writable. Vector commands and C mutators targeting a read-only vector fail with error code
RBC VECTOR READONLY (mapped-variable write errors use Tcl’s TCL WRITE VARNAME code).
Multi-output operations check every destination before changing output values. Recreating an existing
locked vector with vector create is rejected too.
Renaming preserves the state. Destruction, namespace cleanup, array mapping and cache clearing are
allowed. In particular, VECINST clear clears the mapped-variable cache, not the vector values.
Mapped-array writes fail without changing native values. Unsetting an array element also leaves the
values intact; Tcl ignores errors from unset traces, so unset itself can succeed and a subsequent read
reconstructs the element. Whole-array unset retains the existing -watchunset lifetime behaviour.
readonly false deliberately unlocks the vector. This is data protection, not exclusive ownership or
a security boundary. Tcl callbacks may change the state: expression destinations are checked again
after evaluation and before committing the result. Callback side effects are not rolled back.
Loading vectors without Tk¶
Use the rbc::vector package in a Tcl-only interpreter:
package require rbc::vector
::rbc::vector create samples
samples set {1 2 3}
samples expr {samples * 2}
This loads the same Rbc shared library but initializes only its vector commands and C API. It does not
require Tk, a graphical display, argparse, or graphtoolbar. Real and complex vectors, expressions,
array access, and vector client notifications use the same implementation as the full package.
Graphs, winop, and spline are available through the full rbc package. The optional toolbar is loaded
separately with package require rbc::graphtoolbar and requires argparse.
Loading package require rbc later adds the graphical components without recreating the vector
command or existing vectors. Full loading also provides rbc::vector, so either order is supported.
A failed Tk load leaves the vector core usable and full loading can be retried. Package versions
match the shared library version. Use package commands for both paths; the package index handles
the shared binary and its initialization order. Direct load and the C Rbc_Init entry point now
initialize only the vector core; use package require rbc (or Rbc_InitStubs in a consumer) for full
GUI initialization.
This is an initialization split, not a separate binary or reduced build. Building still requires
Tcl/Tk headers and the selected backend dependencies. The shared library’s dynamic dependencies
(for example Cairo or platform graphics libraries) must remain installed even for vector-only use.
The private ::rbc::_initTk command is loader infrastructure, not a public application API.
Vector types¶
Each vector has an immutable numeric type:
real- the default type. Each vector value is a double-precision floating-point number.complex- each vector value contains a double-precision real component and a double-precision imaginary component.
The type is selected when the vector is created:
::rbc::vector create x
::rbc::vector create z -type complex
The VECINST type operation returns the type of an existing vector.
Complex values are represented at the Tcl level as two-element lists:
{real imag}
For example:
::rbc::vector create z -type complex
z set {{1 2} {3 -4} {-2 0.5}}
z index 1
# -> 3.0 -4.0
A real scalar is also accepted where a complex value is expected and is promoted to a complex value with zero
imaginary component. For example, 5 is equivalent to {5 0}.
A vector’s type cannot be changed after creation. Supplying -type for an existing vector is permitted only
when the requested type is the same as its current type. Omitting -type when referring to an existing vector
preserves its current type.
Real vectors whose names contain no parentheses retain the traditional automatic Tcl array mapping. ComplexD vectors do not receive an automatic array mapping, but one may be requested explicitly with -variable orDXS later with VECINST variable.
Graph and spline integration¶
Complex vectors are supported directly by Polar graph elements and by parametric spline interpolation.
Traditional graph, barchart, and stripchart element data remain real-valued. A complex vector supplied
to their ordinary X/Y data options is rejected rather than being implicitly converted to a real part,
magnitude, or another projection.
A widget created by polar can attach a complex vector directly with the element -cdata option:
::rbc::vector create gamma -type complex
gamma set {{0 0} {0.2 0.4} {0.5 0.2}}
::rbc::polar .p -representation smith
.p element create trace -cdata gamma
Polar complex elements support three data formats:
gamma
impedance
admittance
selected with -cdataformat.
The scalar spline interface remains real-valued:
spline natural x y splX splY
spline quadratic x y splX splY
The parametric spline interface operates directly on complex vectors:
spline parametric natural source result samples
spline parametric quadratic source result samples
For example:
::rbc::vector create z -type complex
z set {{0 0} {1 1} {0 2} {-1 1}}
spline parametric natural z smoothZ 100
When a real projection of a complex vector is required for a traditional graph or scalar spline, it can be
derived explicitly with expression functions such as real, imag, abs, or arg:
::rbc::vector create magnitude
magnitude expr {abs(z)}
Vector creation forms¶
Vectors may be created with an initially empty value array:
::rbc::vector create x
A size may be included in the vector specification:
::rbc::vector create x(100)
This creates a vector containing 100 values.
An explicit external index range may also be specified:
::rbc::vector create x(-5:14)
This creates 20 values and sets the vector index offset so that its externally visible indices run from -5 through 14.
The special name #auto requests an automatically generated vector name.
Vector names may be namespace-qualified.
Parentheses in vector names¶
Vector names may contain balanced parentheses, including nested groups. This permits signal names such as
v(out) and i(device) without encoding them. The other name-character restrictions remain unchanged.
::rbc::vector create v(out)
v(out) set {1 2 3 4}
v(out) index 1:2
# -> 2.0 3.0
::rbc::vector create selected
selected set v(out)(1:2)
selected expr {v(out)(1:2) * 2}
Name lookup selects the longest existing name before interpreting an optional final parenthesized group
as an index or range. Thus v(out)(1:2) selects elements of v(out), unless a vector literally named
v(out)(1:2) exists, in which case the exact name wins. Use the instance command’s index or range
operation when a literal name and a range reference would otherwise be identical.
Creation preserves the legacy numeric suffix forms: x(100) creates x with 100 elements, and
v(out)(2:4) creates v(out) with three elements at offset 2. A nonnumeric suffix such as (out) is
part of the name. To create a literal numeric name, use -literal true and specify its length separately:
::rbc::vector create v(1) -literal true -length 100
v(1) index 0:9
The default is -literal false. An exact existing vector name takes precedence even without this option.
The special name #auto still requests an automatically generated name.
Numeric suffixes begin with a digit, sign or colon (ignoring leading whitespace); invalid numeric sizes
and ranges remain errors. -literal true disables suffix interpretation for every supplied name.
Names containing parentheses do not receive an automatic Tcl array mapping, for either numeric type.
Tcl interprets $v(out)(1:2) as array element v(out) followed by literal text (1:2), not as an element
of an array named v(out). Use the vector command, or request a separate array name:
::rbc::vector create v(out) -variable outValues
v(out) set {1 2 3}
set samples $outValues(0:2)
Explicit mapped array names must not contain parentheses. -variable {} disables mapping. This rule also
applies to VECINST variable; a rejected name leaves an existing mapping intact.
In vector expressions, known mathematical function calls retain precedence. If a vector is named sin(x),
sin(x) still calls the function, while {sin(x)} or "sin(x)" inside the expression denotes the vector:
selected expr {{sin(x)} + 1}
selected expr {{sin(x)(0:2)} * 2}
The outer braces delimit the Tcl expression argument; the inner braces quote a vector reference for RBC. This quoting is also useful for names beginning with digits, which otherwise start numeric expressions.
Vector-producing instance operations such as dup, normalize, populate and split also accept literal
destination names with parentheses and do not create automatic array mappings for them.
Vector instances¶
The examples and command descriptions below use VECINST to denote the Tcl command associated with an
individual vector.
For example:
set x [::rbc::vector create x]
$x seq 0 10 0.5
puts [$x length]
Copyright (c) George Yashin