Although GENESIS does not have array variables, it has several objects that contain one or more data structures called the ``interpol_struct'', or ``interpol.'' This data type is used as a field for handling arrays of doubles.
Objects that use interpol_structs:
Object | Names of interpol_structs |
table | table |
table2D | table |
tabgate | alpha beta |
tabchannel | X_A X_B Y_A Y_B Z_A Z_B |
tab2Dchannel | X_A X_B Y_A Y_B Z_A Z_B |
tabcurrent | G_tab I_tab |
ddsyn | transf |
xshape | xpts ypts zpts |
xplot | xpts ypts |
xcell | xpts ypts zpts dia color |
Utility functions that operate on interpol_structs:
Function | Applicable objects | Operation |
setupalpha | tabchannel tabgate | Setup HH rate consts |
setuptau | tabchannel tabgate | Setup HH rate consts |
setupgate | tabgate table | Setup HH rate consts |
tweakalpha | tabchannel | Setup HH rate consts |
tweaktau | tabchannel | Setup HH rate consts |
scaletabchan | tabchannel tabgate | Setup HH rate consts |
setupNaCa | tabcurrent | Model Na-Ca exchanger current |
setupghk | tabcurrent | Solve the GHK equation |
duplicatetable | All | Reallocates interpol |
file2tab | All | Loads interpol from file |
tab2file | All | Dumps interpol to file |
loadtab | All | Loads interpol from command line |
rmsmatch | table | compares waveforms |
shapematch | table | compares waveforms |
curvematch | table | compares waveforms |
newmatch | table | compares waveforms |
An interpol_struct can be accessed by the usual GENESIS setfield and getfield commands:
create table /foo call /foo TABCREATE 100 0 100 setfield /foo table->table[10] 1234 echo {getfield /foo table->table[10]}and it would respond:
1234
The TABCREATE action is called in order to allocate the table. This action, and others which are used for manipulating tables, e.g. TABFILL, are described in the documentation for the particular objects which use interpol_structs.
These objects also have special enhancements to the SET action for operations on the interpol_struct. There are also many utility functions, listed above, that make manipulation of interpol_structs easier.
The SET action is invoked whenever the script command ``setfield'' is used. It is often used when a field needs to receive special treatment. If the field being set is an interpol_struct, then the SET action invokes a function called SetTable. This provides uniform behavior across all classes that use interpol_structs. The SET action in this situation interprets the last argument in a special way. For example, you could say
setfield /foo table /bar/tablewhere /foo and /bar are instances of table objects. In this case /bar/table refers to the table field of /bar, not to an element named /bar/table.
There are three ways in which the destination table (belonging to /foo in the example above) can be manipulated:
setfield foo table bar/table
setfield foo &table bar/table
setfield foo &&table bar/tableThe default is 1. To specify 2, prefix the name of the destination table with an &. To specify 3, prefix the name of the destination table with &&. The last argument can be either another table, or a constant. If it is a constant, then cases 2 and 3 above are errors. The assignment in (a) and arithmetical operators in (c) below are legal for constants, but obviously, the pointer operators in (b) are not. If the second argument is a table, there are several possible options:
setfield foo table bar/table
setfield foo &table &bar/tableFor 3, the pointer to the interpol_struct itself is copied over. This is the recommended way of providing access to shared arrays since future extensions will enable the interpol_struct to keep track of the number of elements which are using it.
setfield foo &&table &bar/table
setfield /foo table =+=/bar/tableOnly option 1 above is allowed. In all cases the results are placed in the first interpol, in this example it is the table on /foo. The following operators are recognized when the second argument is a constant:
+ | adds the constant value to all the table entries |
- | subtracts the constant from all the table entries |
* | multiplies all the table entries by the constant |
/ | divides all the table entries by the constant |
= | assigns all the table entries to the constant |
+ | sums the two tables, placing results in the first. |
- | subtracts the second table from the first. |
* | does an item-by-item product. |
/ | divides the first table by the second, item-by-item. |
= | assigns the values of the first table to the second. |
e | A = exp(B), where A is the first table and B the second. |
E | A = exp10(B) |
l | A = log(B) |
L | A = log10(B) |
f | fits the source table into the destination using interpolation to |
make sure we get a reasonable approximation to all entries. | |
Notes: The memory handling capabilities for interpols have not been implemented. These will free old interpols which are not used by any elements. At present old interpols just get lost without being freed.
Also see the documentation for all listed objects and functions that operate on interpol_structs, especially the table object.
The following example illustrates some of the uses of setfield with interpol_structs:
//genesis // This example illustrates the use of the extended 'SET' action // in manipulating tables. // We use the xpts and ypts tables in the shape for displaying // the effects of the manipulations. create xform /form -wgeom 500 create xcoredraw /form/draw -xmin -1 -xmax 11 -ymin -1 -ymax 1 create xlabel /form/label -label "Displaying a plot of table2 vs table1" create xbutton /form/continue -label "Continue with example" \ -script "do_arith_ops" xshow /form create xshape /form/draw/shape -fg blue -npts 10 // We will use table1 and table2 for storing the original values create table /table1 create table /table2 call /table1 TABCREATE 10 0 10 call /table2 TABCREATE 10 0 10 int i // Set up table 1 as a sine wave. This demonstrates the ordinary // set options for tables. for (i = 0; i <= 10 ; i = i + 1) setfield /table1 table->table[{i}] {i} setfield /table2 table->table[{i}] {sin {i / 2.0}} end // use the special set option to copy the values from table1 and 2 // to xpts and ypts respectively setfield /form/draw/shape xpts /table1/table setfield /form/draw/shape ypts /table2/table // This demonstrates using constants for arithmetic operations function do_arith_ops setfield /form/draw/shape fg red ypts =/=2.0 setfield /form/label label "Now all y coords have been halved" setfield /form/continue script "do_more_arith_ops" end // This demonstrates using other tables for arithmetic operations function do_more_arith_ops setfield /form/draw/shape fg green ypts =-=/table2/table setfield /form/label label \ "Now table2 has been subtracted from the y coords" setfield /form/continue script "do_new_interpol" end function do_new_interpol // This demonstrates allocating a new interpol for ypts setfield /form/draw/shape fg yellow &&ypts /table2/table setfield /form/label label\ "Now a new interpol has been allocated. It uses values from table2" setfield /form/continue script "do_interpol_ptr" end // this demonstrates copying over a pointer to an interpol for xpts function do_interpol_ptr setfield /form/draw/shape fg black &&xpts &/table1/table setfield /form/label label \ "Now the xpts interpol uses the same pointer as table1" setfield /form/continue script "do_interpol_ptr2" end // This shows that the interpol for table1 and xpts are the same // but table2 and ypts are distinct. We change both table1 and 2, // but xpts is the only one that is affected. function do_interpol_ptr2 setfield /table1 table->table[0] 1 setfield /table2 table->table[0] 1 // This is a hack to force the draw to update, since there is no // way for it to know that anything in it has changed. setfield /form/draw xmin -1.0001 setfield /form/label label \ "Here we change table1 and 2. Only xpts changes." setfield /form/continue script "quit" label "quit" end