maxima and converting output of variable to float - equation

I can get maxima to solve an equation but can't figure out why it won't show it's numerical value without typing the extra command/step of float(%). Is there away to automatically convert a solved variable to a numerical format.
Example of equation below:
kill(all); alpha:float(.0014931); endfreq:50; dursec:1200; solve(alpha=log(startfreq/endfreq)/dursec,float(startfreq));
what comes back is
startfreq=50%e(44793/25000)
I would like it to say 299.988 instead

Well, Maxima prefers exact results (i.e., integers, rational numbers, and symbolic constants) instead of inexact (i.e., float and bigfloat numbers). If you want to work only with numerical solutions, take a look at find_root. E.g.:
(%i1) [alpha, endfreq, dursec] : [0.0014931, 50, 1200] $
(%i2) find_root (alpha = log(startfreq / endfreq)/dursec, startfreq, 1, 500);
(%o2) 299.9881594652534
Note that to use find_root you must know an interval (here 1 to 500) which contains a root of the equation.

Related

Output_precision(); Octave

Hi after calling this code (Octave) I get an answer with 7 digits of precision, I need only 6. It is worth mentioning that on different data-set the output is normal(with 6 digits);
output_precision(6);
Prev
output:
Prev =
0.1855318
0.2181108
0.1796457
I know this is a little late but I wanted to add an answer for anyone with the same question in the future.
According to the function reference for output_precision(), the argument passed to the function (in this case, 6) specifies the minimum number of significant figures, which only guarantees that future numeric output won't have less than that number of significant figures.
From what I've seen, if you use output_precision(new_val) before displaying an array (e.g., Prev in the question), then octave will round the element with the least digits before the decimal place to have new_val significant figures and then all other elements will be rounded to have the same number of digits after the decimal place as that initial rounded result. If you use a statement to output a single value instead of an array, then the output is just rounded to new_val significant figures. However, I don't know if this behavior is guaranteed .
Here's a short example of what I mean:
% array defined with values having 5 digits after decimal
F = [401.51670 313.70753 -88.55225 188.50067 280.21988 354.51821 54.51821 350];
output_precision(4)
F
output_precision(6)
F
Output:
F =
401.52 313.71 -88.55 188.50 280.22 354.52 54.52 350.00
F =
401.5167 313.7075 -88.5523 188.5007 280.2199 354.5182 54.5182 350.0000
It can be a little quirky if you try to round the values too much. When I used output_precision(3) and then output F, the numbers were actually rounded as if my system's default precision, 5, was still active. However, when I used elements with only 2 or 3 digits after the decimal to define another array, it displayed as expected with output_precision(3).
Check out Octave Forge if you ever need docs for octave features. It's not perfect but it's something. Hope this was helpful.

Get right-hand side of equation

I am calling the function mnewton(0=expr, alpha, %pi/4) to get the root of a rather complex equation expr.
%(i1) mnewton(0=expr, alpha, %pi/4)
%(o1) [alpha=0.678193754078621]
I need to apply another function to this result (e.g. sin) and then want to plot it. Just linking the functions does not work:
%(i2) sin(mnewton(0=expr, alpha, %pi/4)[1])
%(o2) sin(alpha=0.678193754078621)
This is because the expression alpha=0.678193754078621 is not a number. How do I convert alpha=0.678193754078621 to just 0.678193754078621?
I can't just copy the numerical value and add it manually as I want to plot this and my expr will have a different root for each y.
The function rhs(expr) does exactly that.
Check the manual for more information on this.

Expr for float values in TCL

Calculating float values
tclsh
% expr 0.2+0.2
0.4
% expr 0.2+0.1
0.30000000000000004
%
Why not 0.3??
Am i missing some thing.
thanks in advance.
Neither 0.1 or 0.2 have an exact representation in IEEE double precision binary floating point arithmetic (which Tcl uses internally for expressions involving fractional values, as there's good hardware support for them). This means that the values you are computing with are never exactly what you think they are; instead, they're both very slightly more (as it happens; they could also have been slightly less in general). When you add 0.2+ε1+0.1+ε2, it can happen that ε1+ε2 can add up to more than the threshold where 0.3 (another imprecisely represented value) becomes the next exactly represented value above it. This is what you have observed. It's also inherent in the way floating point mathematics works in a vast array of languages; only integer arithmetic (or fractional arithmetic capable of being expressed as exact multiples of some power of 2, e.g., 0.5, 0.25, 0.125) is guaranteed to be exact.
The only interesting thing of note here is that Tcl 8.5 and 8.6 prefer to render floating point numbers with the minimal number of digits required to get the exact value back when re-parsed. If you want to get a fixed number of digits (e.g., 8) try using format when converting:
format %.8f [expr 0.2+0.1]
This behavior exists in almost all programming languages, e.g. Ruby, Python, etc.
The suggestion here is try to avoid storing numbers in floating points, use integer whenever possible. The bottom line is do not use floating points in a comparison.

Is there a "native" way to convert from numbers to dB in Tcl

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.

distributive property for product of maxterms

I am unsure how to use the Distributive property on the following function:
F = B'D + A'D + BD
I understand that F = xy + x'z would become (xy + x')(xy + z) but I'm not sure how to do this with three terms with two variables.
Also another small question:
I was wondering how to know what number a minterm is without having to consult (or memorise) the table of minterms.
For example how can I tell that xy'z' is m4?
When you're trying to use the distributive property there, what you're doing is converting minterms to maxterms. This is actually very related to your second question.
To tell that xy'z' is m4, think of function as binary where false is 0 and true is 1. xy'z' then becomes 100, binary for the decimal 4. That's really what a k-map/minterm table is doing for you to give a number.
Now an important extension of this: the number of possible combinations is 2^number of different variables. If you have 3 variables, there are 2^3 or 8 different combinations. That means you have min/maxterm possible numbers from 0-7. Here's the cool part: anything that isn't a minterm is a maxterm, and vice versa.
So, if you have variables x and y, and you have the expression xy', you can see that as 10, or m2. Because the numbers go from 0-3 with 2 variables, m2 implies M0, M1, and M3. Therefore, xy'=(x+y)(x+y')(x'+y').
In other words, the easiest way to do the distributive property in either direction is to note what minterm or maxterm you're dealing with, and just switch it to the other.
For more info/different wording.