differences between double colon and global variables use? - tcl

Very recently I found out about the namespace concept and the use of double-colon (::) for program variables.
Before I start reshaping all my scripts, I wanted to know if there is a real difference between accessing a variable with the global keyword and with the double colon syntax.
e.g.
set var bla
proc kuku {} { puts $::var }
vs.
proc gaga {} {global var ; puts $var}
In both cases I'm getting 'bla' written to my screen.
What am I missing?
I understand that editing the variable will be a bit problematic (is it even possible?), but for read-only vars, is there a difference between the two methods?

They're talking about the same variable. With the ::var form, you're using the fully-qualified name, whereas with the form with global you're making a local link to the global variable (which really is a pointer to the global variable). Reading from or writing to them should work exactly the same, whichever way you choose.
There is a measurable difference between the two. With global, you've got the extra cost of setting up the link, but thereafter for the remainder of the procedure the cost per use (read or write) is quite a lot lower. With the other form, you're not paying any setup overhead, but the per-use cost is higher. For one use only, the cost of the two are pretty similar. If you're using the variable several times, global is cheaper. OTOH, sometimes it is clearer to use the fully qualified version anyway (particularly true with vwait and trace) despite the reduction in speed.
I find that I access the ::env and ::tcl_platform arrays using their fully-qualified form, but most other things will get accessed via global. That's just my preference though.
Here's an example interactive session:
% set x 1
1
% proc y1 {} {incr ::x;return ok}
% time { y1 } 10000
0.5398216 microseconds per iteration
% proc y2 {} {global x;incr x;return ok}
% time { y2 } 10000
0.4537753 microseconds per iteration
% proc z1 {} {return $::x}
% time { z1 } 10000
0.4864713 microseconds per iteration
% proc z2 {} {global x; return $x}
% time { z2 } 10000
0.4433554 microseconds per iteration
(I wouldn't expect you to get the same absolute figures as me. Do your own performance testing. I would expect similar relative figures…)

Related

Dirac function in TCL

I am using a structural software that uses TCL as a programming language.
Does anyone how to define dirac functions in TCL? From the examples I got hold of, 4 arguments are required. What do they correspond to?
This is how the function is defined in my examples:
#
diract(tint,0*dt,dt,dt)
#
Thank you in advance
PS: I am struggling to find some good documentation. Any recommendation ?
Given that we have a finite step size (because we're using IEEE double precision floating point, the Dirac delta function is just this:
proc tcl::mathfunc::delta {x} {
expr {$x == 0.0 ? 4.49423283715579e+307 : 0.0}
}
That gives a delta function with a very large impulse at the origin (where the width of the impulse is determined by the size of the smallest non-denormalized number; that number is one of the largest that can be represented by floating point without using infinity).
That's not all that useful, as it's using floating point equality in its definition (and that rightfully has some major caveats attached to it). More usefully is fact that the integral of it is such that it is 0 when x is less than 0 and 1 when x is more than 0.
I'm not sure what the arguments you're looking to provide mean, especially given that 0*dt one of them.

Double values lose precision in tcl after string\list operations

While working with tcl, I discover such a behavior: when I looping over double variable it lose its precision.
set dbl [expr { double(13.0/7.0) }]
set dbl2 [expr { double(13.0/7.0) }]
foreach a $dbl {
}
if { $dbl == $dbl2 } {
puts "\$dbl == \$dbl2"
} else {
puts "\$dbl != \$dbl2" ;# they will be not equal
}
As I soon find out, when you use operations that work with strings or lists (e.g. llength, lindex, string first, rsub, foreach, etc.) the double representation of variable will be replaced with string representation which will be created or was created earlier, based on $tcl_precision value. Furthermore, every copy of this double variable that was created with set command, also will be spoiled.
Is there a way not to lose precision after such operations in tcl8.4 and without forcing tcl_precision to some fixed value?
P.S. set tcl_precision 0 will work only in tcl8.5 or above versions.
From Tcl 8.5 onwards, your code should Just Work. Considerable effort was put into 8.5 to make the default conversion of doubles to strings (and hence to other types) not lose information. It also tries to use the minimum number of digits to do this on the grounds that this minimises the amount of surprise presented to people; yes, we had a real expert working on this.
For 8.4 and before, set tcl_precision to 17. That guarantees that no significant bits are lost, though the representation used may be considerably longer than minimal.

What is the difference between global and :: in TCL?

I am working with an EDA SW. It requires me to rely on global variables.
Say I have a proc, and I am looking for a global variable CCK_FOO. I have 2 choices:
Use global CCK_FOO within the code.
Use ::CCK_FOO
In terms of "management level", these appear identical. Is there an "under the hood" pro and con for either of the methods? I actually prefer using ::, as it minimizes the chances of accidental override.
Under the hood, using ::CCK_FOO goes through the parsed variable name route every time the execution engine uses it, whereas global CCK_FOO allows the engine to set up a local variable (with a local variable table — LVT — slot) that is linked to the global variable. Accesses via the LVT is much faster because that's just an index into a C array (and an extra pointer dereference because it's a link) whereas looking up a global variable means doing a hash table lookup (there's a hash table for variables in the global namespace implementation). The actual internal parse of ::CCK_FOO into :: and CCK_FOO is cached.
In practical terms, it's perhaps slightly faster to use ::CCK_FOO if you are only accessing a variable once, but as soon as you use it twice (let alone more) you get better performance by paying the extra cost of global CCK_FOO and accessing it via LVT indexing.
% proc style1 {} {
set ::CCK_FOO abc
}
% proc style2 {} {
global CCK_FOO
set CCK_FOO abc
}
% time { style1 } 100000
0.52350635 microseconds per iteration
% time { style2 } 100000
0.5267007100000001 microseconds per iteration
Note, times between code above and code below are not comparable as they do different amounts of other work. Look instead at the differences in timings between style1 and style2.
% proc style1 {} {
set ::CCK_FOO [string reverse $::CCK_FOO]
}
% proc style2 {} {
global CCK_FOO
set CCK_FOO [string reverse $CCK_FOO]
}
% time { style1 } 100000
0.9733970200000001 microseconds per iteration
% time { style2 } 100000
0.78782093 microseconds per iteration
# Calibration...
% time { string reverse abc } 100000
0.28694849 microseconds per iteration
As you can see, with just two accesses, we're getting quite a lot of speedup by using global.

Function types declarations in Mathematica

I have bumped into this problem several times on the type of input data declarations mathematica understands for functions.
It Seems Mathematica understands the following types declarations:
_Integer,
_List,
_?MatrixQ,
_?VectorQ
However: _Real,_Complex declarations for instance cause the function sometimes not to compute. Any idea why?
What's the general rule here?
When you do something like f[x_]:=Sin[x], what you are doing is defining a pattern replacement rule. If you instead say f[x_smth]:=5 (if you try both, do Clear[f] before the second example), you are really saying "wherever you see f[x], check if the head of x is smth and, if it is, replace by 5". Try, for instance,
Clear[f]
f[x_smth]:=5
f[5]
f[smth[5]]
So, to answer your question, the rule is that in f[x_hd]:=1;, hd can be anything and is matched to the head of x.
One can also have more complicated definitions, such as f[x_] := Sin[x] /; x > 12, which will match if x>12 (of course this can be made arbitrarily complicated).
Edit: I forgot about the Real part. You can certainly define Clear[f];f[x_Real]=Sin[x] and it works for eg f[12.]. But you have to keep in mind that, while Head[12.] is Real, Head[12] is Integer, so that your definition won't match.
Just a quick note since no one else has mentioned it. You can pattern match for multiple Heads - and this is quicker than using the conditional matching of ? or /;.
f[x:(_Integer|_Real)] := True (* function definition goes here *)
For simple functions acting on Real or Integer arguments, it runs in about 75% of the time as the similar definition
g[x_] /; Element[x, Reals] := True (* function definition goes here *)
(which as WReach pointed out, runs in 75% of the time
as g[x_?(Element[#, Reals]&)] := True).
The advantage of the latter form is that it works with Symbolic constants such as Pi - although if you want a purely numeric function, this can be fixed in the former form with the use of N.
The most likely problem is the input your using to test the the functions. For instance,
f[x_Complex]:= Conjugate[x]
f[x + I y]
f[3 + I 4]
returns
f[x + I y]
3 - I 4
The reason the second one works while the first one doesn't is revealed when looking at their FullForms
x + I y // FullForm == Plus[x, Times[ Complex[0,1], y]]
3 + I 4 // FullForm == Complex[3,4]
Internally, Mathematica transforms 3 + I 4 into a Complex object because each of the terms is numeric, but x + I y does not get the same treatment as x and y are Symbols. Similarly, if we define
g[x_Real] := -x
and using them
g[ 5 ] == g[ 5 ]
g[ 5. ] == -5.
The key here is that 5 is an Integer which is not recognized as a subset of Real, but by adding the decimal point it becomes Real.
As acl pointed out, the pattern _Something means match to anything with Head === Something, and both the _Real and _Complex cases are very restrictive in what is given those Heads.

How could I make this procedure more elegant?

I have a servo I'm controlling that is moving an object closer and closer to a sensor, trying to trigger it.
I want the distance to start at 15.5. However, in each iteration, I want it to decrease the distance .1, until the sensor triggers. For convenience sake, I'd like to exit the while loop with the variable $currentHeight set to this triggering height, so I've placed the decrement line at the beignning of the loop.
But, I've had to hardcode a 15.6 starting point before the while loop so that it will decrement in the first line of the loop to 15.5.
That doesn't seem elegant. Any suggestions on how to spruce this up?
By the way, this is Tcl for all you old school and obscure programmers. ;)
Code:
set currrentDistance 15.6
set sensorStatus 4
while {$sensorStatus == 1)} {
set currentDistance [expr $currentDistance - .1]
moveServo $currentHeight
set sensorStatus [watchSensor 2]
}
I'd use a for loop:
for {set d 155} {$d > 0} {incr d -1} {
set currentDistance [expr {$d * 0.1}]
moveServo $currentHeight
set sensorStatus [watchSensor 2]
# If we've found it, stop searching!
if {$sensorStatus == 1} break
}
This has the advantage of firstly having a limit against physical impossibility (no point in grinding the robot to pieces!) and secondly of doing the iteration with integers. That second point is vital: binary floating point numbers are tricky things, especially when it comes to iterating by 0.1, and Tcl (in common with many other languages) uses IEEE floating point arithmetic internally. The way to avoid those problems is to iterate with integers and have a bit of code to convert to floating point (e.g., by dividing by 10). Think in terms of dealing with counting down in units of 0.1. :-)
One other lesser stylistic point. Put {braces} round expressions as it boosts safety and performance. (The performance boost comes because the runtime knows it can't have weird expression fragments, which are also what would count as unsafe. Not that it is critical in this code because of the dependance on the servo hardware, but it's a good habit to get into.)
I don't know Tcl, but it could look something like this:
set currrentDistance 15.5
set sensorStatus 4
while {true} {
moveServo $currentHeight
set sensorStatus [watchSensor 2]
if {$sensorStatus == 1} then {break};
set currentDistance [expr $currentDistance - .1]
}