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]
}
Related
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.
I have used some tcl code in a design tool to get the list of standard cells in a single list.
Tcl has a limitation of processing a large number of elements to read from any list. How do I split these list of standard cells in a single data structure for the tool to read?
If you've got a big list that you've got to split into small chunks for processing and don't want to just do all the pieces one by one with foreach, you can do this:
set big_list {lots and lots and lots...}
set index 0
set stride 10
while true {
set chunk [lrange $big_list $index [expr {$index + $stride - 1}]]
# Nothing left; got to the end
if {![llength $chunk]} break
incr index $stride
process_chunk $chunk
}
Tune the stride size for how much you can feed through. (Theoretically, you can do auto-tuning of the stride length if there's some complex limit involved. Practically, just pick something by hand that works and isn't too inefficient; auto-tuning algorithms are always quite a lot more complicated.)
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…)
dB or decibel is a unit that is used to show ratio in logarithmic scale, and specifecly, the definition of dB that I'm interested in is X(dB) = 20log(x) where x is the "normal" value, and X(dB) is the value in dB. When wrote a code converted between mil. and mm, I noticed that if I use the direct approach, i.e., multiplying by the ratio between the units, I got small errors on the opposite conversion, i.e.: to_mil [to_mm val_in_mil] wasn't equal to val_in_mil and the same with mm. The library units has solved this problem, as the conversions done by it do not have that calculation error. But the specifically doesn't offer (or I didn't find) the option to convert a number to dB in the library.
Is there another library / command that can transform numbers to dB and dB to numbers without calculation errors?
I did an experiment with using the direct math conversion, and I what I got is:
>> set a 0.005
0.005
>> set b [expr {20*log10($a)}]
-46.0205999133
>> expr {pow(10,($b/20))}
0.00499999999999
It's all a matter of precision. We often tend to forget that floating point numbers are not real numbers (in the mathematical sense of ℝ).
How many decimal digit do you need?
If you, for example, would only need 5 decimal digits, rounding 0.00499999999999 will give you 0.00500 which is what you wanted.
Since rounding fp numbers is not an easy task and may generate even more troubles, you might just change the way you determine if two numbers are equal:
>> set a 0.005
0.005
>> set b [expr {20*log10($a)}]
-46.0205999133
>> set c [expr {pow(10,($b/20))}]
0.00499999999999
>> expr {abs($a - $c) < 1E-10}
1
>> expr {abs($a - $c) < 1E-20}
0
>> expr {$a - $c}
8.673617379884035e-19
The numbers in your examples can be considered "equal" up to an error or 10-18. Note that this is just a rough estimate, not a full solution.
If you're really dealing with problems that are sensitive to numerical errors propagation you might look deeper into "numerical analysis". The article What Every Computer Scientist Should Know About Floating-Point Arithmetic or, even better, this site: http://floating-point-gui.de might be a start.
In case you need a larger precision you should drop your "native" requirement.
You may use the BigFloat offered by tcllib (http://tcllib.sourceforge.net/doc/bigfloat.html or even use GMP (the GNU multiple precision arithmetic library) through ffidl (http://elf.org/ffidl). There's an interface already defined for it: gmp.tcl
With the way floating point numbers are stored, every log10(...) can't correspond to exactly one pow(10, ...). So you lose precision, just like the integer divisions 89/7 and 88/7 both are 12.
When you put a value into floating point format, you should forget the ability to know it's exact value anymore unless you keep the old, exact value too. If you want exactly 1/200, store it as the integer 1 and the integer 200. If you want exactly the ten-logarithm of 1/200, store it as 1, 200 and the info that a ten-logarithm has been done on it.
You can fill your entire memory with the first x decimal digits of the square root of 2, but it still won't be the square root of 2 you store.
I am looking for a clean way to list the (8 bit) integers whose binary representation is not the same as another integer up to rotation and reflection.
For example the list will probably start as
0
1
(2=10b is skipped because you can rotate the bits in 1, therefore all powers of 2 are skipped. Also every number except 0 will be odd)
3=11b
5=101b
7=111b
9=1001b
11=1011b (so 13=1101b will be skipped because 11010000b is a reflection of 1101b which can then be rotated to the right 4 times )
.
.
.
Also ideally how could this be generalized to numbers with different numbers of bits, (16, 32, or just n) and other bases beside 2.
Since #John Smith thought my comment was a good answer, here it is an answer.
The answers here may be illuminating.
Thanks to Jeffromi for explaining the problem better -- I've deleted my previous answer.
Here's another solution in Perl. Perl is a good language for this sort of problem because it makes it easy to treat numbers as text and text as numbers.
i: for $i (0..255) {
$n1 = sprintf "%08b", $i; # binary representation of $i
$n2 = $n1; # "unreflected" copy of $n1
$n3 = reverse $n1; # "reflection" of $n1
for $j (1..8) {
$n2 = chop($n2) . $n2; # "rotate" $n2
$n3 = chop($n3) . $n3; # "rotate" $n3
next i if $found{$n2} or $found{$n3};
}
# if we get here, we rotated $n2 and $n3 8 times
# and didn't get a nonsymmetric byte that we've
# seen before -- this is a nonsymmetric byte
$found{$n1}++;
print "$i $n1\n";
}
This isn't as simple as the previous solution, but the jist is to try out all 16 combinations (2 reflections x 8 rotations) and compare them with all of the nonsymmetric bytes you've seen before.
There's a operator for bit shifting with rotation in Perl, but the chop($num) . $num idiom I used generalizes better to problems with base n.
You can use a sieve, similar to the sieve of Eratosthenes for prime numbers.
Use a bit array (BitSet in Java) with one bit for each number.
Initially mark all bits.
Go sequentially through the bit array until you find the next bit that is set at index n, this is a number in your set. Then clear the bits of all other numbers that can be reached from n via rotation and mirroring.
On today's machines this is feasible up to 32 bits, which would use 512MB of memory.
An alternative solution to Eratosthenes' Sieve would be to construct a test T(k) that returns True or False for any given k.
It would be slower, but this way no storage would be needed, so it would extend more readily to arbitrary data length.
If you simplify the problem for a moment, and say we are simply looking to discard reflections, then it would be easy:
T_ref(k) returns true iff k <= Reflection(k).
As for rotating bits, exactly the same can be done:
T_rot(k) returns true iff k == MIN{the set of all rotations of k}
You can think of dividing your integers up into a bunch of equivalence classes E(k) where E(k) is the set of all reflection&rotation permutations of k.
You might want to take a moment to satisfy yourself that the set of natural numbers N partitions itself readily into such disjoint subsets.
Then the set
{k s.t. k == MIN(E(k)) }
will guarantee to contain exactly one element from each equivalence class.
This would make a really nice interview question.