Python Concepts/Using Python's Decimal module

=Objective=


 * Learn about Python's Decimal module.
 * Learn about Decimal objects.
 * Review examples of code containing Decimal objects.
 * Learn how to use Decimal objects to perform calculations on complex numbers.
 * Become familiar with numbers containing many thousands of decimal digits.
 * Create a new class CompleX.
 * Use class CompleX and Python's Decimal module to solve the cubic equation.

=Lesson=

Calculations using Python's Decimal module can be performed with (almost) any precision selectable by the user. Unfortunately many functions which you might expect to find in the module don't exist, for example, trigonometric functions and functions that manipulate complex numbers. For these functions you have to find them elsewhere or write them for yourself.

Here are some examples that highlight the power of Python's Decimal Module.

Conversion to Decimal object
Several different objects are convertible to Decimal object. Type int converts exactly:

Precision is not applied when the Decimal object is initialized or displayed. Default precision of 28 is applied when the Decimal object is used:

Although conversion is not necessary, Decimal object converts exactly.

Conversion from float to Decimal is tricky:

Conversion from float is accurate if correct precision for floats is applied.

Also, conversion from float is accurate if float is correctly formatted.

For simple, accurate conversion to Decimal, convert float to str first:

Conversion from complex to Decimal:

Conversion from str representing number to Decimal is accurate.

eval is more forgiving than Decimal.

Conversion from DecimalTuple is accurate:

Conversion from well formed list or tuple is accurate:

Using Decimal objects
Decimal objects work well with the usual arithmetic operators:

If you are doing much heavy math containing cube roots, it might be advantageous for you to write your own cube root function using Newton's method, for example. Newton's method is much faster than raising a number to the power (1/3).

Decimal objects work well with many of the familiar built-in functions:

Logical operations
The Decimal object  has the appearance of a binary number and logical operations act on Decimal objects whose only digits are

When using python's decimal module for logical operations on integers, convert int to appropriate Decimal object first.

After the logical operation convert Decimal object with appearance of binary number to int.

Context objects and attributes
Contexts are environments for arithmetic operations. They govern precision, set rules for rounding, determine which signals are treated as exceptions, and limit the range for exponents.

After the decimal module has been imported, three supplied contexts are available:

After the decimal module has been imported, the current context is the same as DefaultContext.

After importing the decimal module, set the current context (if necessary) as appropriate for your planned use of the decimal module.

For a list of valid signals:

To create a new context copy an existing context:

or use the constructor Context:

To modify a context:

To set current context:

The rules are:


 * A bad operation sets a flag.
 * A good operation does not clear a flag.
 * Before a decimal operation set traps and clear flags.
 * After a decimal operation process exceptions and check flags.

Methods
Many of the methods available for Context objects have the same names as corresponding methods available for Decimal objects, for example : max, quantize, shift and sqrt.

However they usually take an extra argument so that they make sense when attached to Context object;

Others such as clear_traps, clear_flags make sense only when attached to Context object.

Context objects are useful if you want to perform an arithmetic operation in a temporary environment without changing current environment.

Also if you want to apply a trap to a conversion without affecting current environment:

To check the result of arithmetic operation in a temporary environment:

Is Decimal object int?

Making the Decimal object
The following function verifies that we are working with Decimal objects. It provides for a tuple containing two decimal objects to simulate a complex number.

=Trigonometric Functions=

The following trigonometric functions are sufficient to convert from complex type polar to complex type rectangular and vice-versa.

For the functions $$\cos x$$ and $$\sin x$$ see Recipes.

arctan x
We'll try $\arctan x$ first because it's easily understood and implemented, and it can be used to calculate $$\pi$$ because the result of this expression (as in all theoretical math) is in radians.

$$ \arctan x = \sum^{\infty}_{n=0} \frac{(-1)^n}{2n+1} x^{2n+1} = x-\frac{x^3}{3} + \frac{x^5}{5}-\cdots \text{for }|x| \le 1,\ x\neq\pm i $$

Calculating π
There are many ways to calculate $$\pi$$. For example:

$$\pi = 6*\arctan (\tan 30) = 6*\arctan(\frac{\sqrt{3}}{3}).$$

Based on the following, we will perform six calculations of $$\pi$$ and compare the results.

$$\pi = 30*\arctan (\tan 6)$$

$$\pi = 24*\arctan (\tan 7.5)$$

$$\pi = 12*\arctan (\tan 15)$$

$$\pi = 8*\arctan (\tan 22.5)$$

$$\pi = 6*\arctan (\tan 30)$$

$$\pi = 5*\arctan (\tan 36)$$

All six calculations agree to 500 digits of precision and π is available globally as a Decimal object.

tan (Θ / 2)
$\tan \frac {\theta}{2}$$$ = \csc \theta - \cot \theta$$.

decATAN2 (y, x)
For the corresponding function using floating point arithmetic see math.atan2(y, x)

This function invokes $$arctan(x)\ 0 \le x \le 1$$.

If $$\tan \theta > 1,\ x = \frac{1}{\tan \theta}$$ and the result is $$\frac{\pi}{2} - \arctan(x).$$

However this function invokes $$\arctan(x)$$ with a value less than $$0.325$$ so that the expression $$x^{2n+1}$$ in the expansion of $$\arctan x$$ vanishes as rapidly as possible. Therefore:

$$75 = 90 - \arctan (\frac{1}{\tan 75})$$

$$68 = 4 \arctan (\tan \frac{68}{4})$$

$$32 = 2 \arctan (\tan \frac{32}{2})$$

$$12 = \arctan (\tan 12)$$

degreesToRadians (θinDegrees)
=Complex Functions=

Within the context of this page a complex number is contained in a tuple with three members, thus:

The above tuple represents complex number $$modulus\ *\ (\ \cos(phaseInDegrees)\ +\ 1j*\sin(phaseInDegrees)\ )$$.

Or:

where $$realPart, imaginaryPart$$ are the rectangular coordinates of complex number $$realPart\ +\ 1j*imaginaryPart$$.

The four values $$modulus, phaseInDegrees, realPart, imaginaryPart$$ are all Decimal objects.

The rectangular format is useful for addition and subtraction of complex numbers.

The polar format is useful for raising a complex number to a power including a power less than unity.

Both formats are useful for multiplication, division and square root.

When working with polar format it's generally more advantageous to work with a positive modulus. Therefore:

$$-n * (\cos \phi + 1j*\sin \phi) = n * (\cos (\phi \pm 180) + 1j*\sin (\phi \pm 180))$$

and, for example:

$$\sqrt{-4} = \sqrt{-4(\cos 0 + 1j*\sin 0)} = \sqrt{4(\cos 180 + 1j*\sin 180)} = 2(\cos 90 + 1j*\sin 90) = 2*1j*1 = 2j$$

and the other sqrt of $$-4$$ is:

$$\sqrt{4(\cos (-180) + 1j*\sin (-180))} = 2(\cos (-90) + 1j*\sin (-90)) = 2*1j*(-1) = -2j$$.

Both of the following complex tuples equate to 0:

The following functions will enable us to do some serious math with complex numbers, such as solving the cubic equation with three real roots.

checkComplex(x)
This function verifies that the object is a valid complex tuple.

complexCUBEroot (x)
=class CompleX=

The above code highlights the power of Python in a new class called CompleX. When a new instance of this class is created, it can be accessed through its attributes and changed through its methods with the simplest of syntax.

Seemingly complicated functions such as complex cube root can be implemented in only a few lines of simple code.

Examples
=Solving the cubic equation=

[[File:20190505Cubic.png|thumb|400px| Figure 1: Cubic function and X intercepts. Origin at point $$(0,0)$$. Intercepts at points $$(3,0),\ (-1,0),\ (-2.5,0)$$

]]

The cubic equation is expressed thus: $$ax^3 + bx^2 + cx + d = 0$$ where both $$a, d$$ are non-zero.

We will solve the equation $$2x^3 + x^2 - 16x - 15 = 0$$ as an example of the use of Python's Decimal module and the new class CompleX. See Figure 1.

The depressed cubic and Vieta's substitution
Let $$x = \frac{-(b + t)}{3a}$$, substitute this value of $$x$$ in the cubic equation and produce the depressed cubic $$t^3 + pt + q = 0.$$

Let $$t = w - \frac{p}{3w}$$, substitute this value of $$t$$ in the depressed equation and produce the quadratic: $$W^2 + qW + C^3 = 0$$ where $$W = w^3$$.

Therefore, $$W = \frac{-q \pm \sqrt{q^2 -4C^3}}{2}$$.

The cube roots
[[File:20190326Circle.png|thumb|400px| Figure 2: Three cube roots of W. $$w_1$$ = RooT1; $$w_2$$ = RooT2; $$w_3$$ = RooT3. $$W\ =\ w_1^3\ =\ w_2^3\ =\ w_3^3$$. Phase of $$W\ =\ \alpha$$

Phase of $$w_1\ =\ \beta\ =\ \frac{\alpha}{3}$$ Phase of $$w_2\ =\ \beta\ +\ 120.$$ Phase of $$w_3\ =\ \beta\ -\ 120.$$ ]]

The three roots of the given cubic are $$-1, 3, -2.5$$.

=Assignments=

When calculating $$\pi$$:
 * Calculate the value of $$\pi$$ to 10,000 places of decimals.

What are the square roots of $$N$$?
 * $$N$$ = $$(9, 60,$$ 'polar'$$)$$.

$$(\sqrt{9},\ \frac{60}{2},$$ 'polar'$$)\ =\ (\pm3,\ 30,$$ 'polar'$$)$$. $$(-3,\ 30,$$ 'polar'$$)$$ = $$(3,\ 30\pm 180,$$ 'polar'$$)$$

What is the number $$N$$? What are the other two cube roots of $$N$$?
 * $$r_1 = (2, 60,$$ 'polar'$$)$$ is one of the cube roots of a certain number $$N$$.

$$r_1 = 2(\cos 60 + 1j*\sin 60).$$ $$N = r_1^3 = 2^3(\cos(60*3) + 1j*\sin(60*3)) = 8(\cos 180 + 1j*\sin 180) = 8(-1) = -8$$. The other two cube roots of $$N$$ are: $$r_2, r_3 = (2, 60\pm 120,$$ 'polar'$$)$$


 * Given that CX1 is type CompleX, add method sqrt to class CompleX so that the expression CX1.sqrt returns the square root of CX1 as type CompleX.

=Further Reading or Review=


 * Previous Lesson: Iteration and Iterators
 * This Lesson:Using Python's Decimal module
 * Next Lesson: Interfacing with Unix
 * Course Home Page

=References=

Python's built-in functions:

"abs",

Python's documentation:

Decimal fixed point and floating point arithmetic, A first look at classes