I'm trying to implement the simplex method in Python so I need to use the Gaussian elimination on arrays. Very often fractions come up and for more clarity and precision I would like to keep the fractional form instead of using floats. I know the 'fractions' module but I'm struggling to use it. I wrote my code using this module but the arrays are always returned with floats. Isn't it possible to print an array with fractions inside ? On this basic example :
>>> A
array([[-1., 1.],
[-2., -1.]])
>>> A[0][0] = Fraction(2, 3)
>>> A
array([[ 0.66666667, 1. ],
[-2. , -1. ]])
I would like to have
array([[2/3, 1. ],
[-2., -1. ]])
It seems numpy always switches to floats
vectorize(Fraction)(A) : this will call Fraction on each element of the array and return the result. This also automatically converts the result array to an object-typed array.
We can convert an integer, a floating point number or a string to a fraction in python . To convert a ratio of two integers to fraction, we use Fraction() method of fractions module and pass the numerator as the first argument and the denominator as the second argument.
Convert a fraction to a floating-point number: float() You can convert Fraction to a floating-point number with float() . The result of an operation between Fraction and float is automatically converted to float .
You can also convert the entire array to an object
array of Fraction
objects, by abusing the element-wise conversion of numpy arrays under arithmetic operations. (Note: this requires the original array to be an integer array, since arithmetic between float
s and Fractions
produce float
s.)
>>> A = np.array([[-1, 1],[-2, -1]])
array([[-1, 1],
[-2, -1]])
>>>
>>> A.dtype
dtype('int64')
>>>
>>> A = A + Fraction()
>>> A
array([[Fraction(-1, 1), Fraction(1, 1)],
[Fraction(-2, 1), Fraction(-1, 1)]], dtype=object)
With the array in this format, any further arithmetic performed will be over elements of type Fraction
.
Since Fraction
s are not a native NumPy dtype, to store a Fraction
in a NumPy array you need to convert the array to object
dtype:
import numpy as np
from fractions import Fraction
A = np.array([[-1., 1.],
[-2., -1.]]) # <-- creates an array with a floating-point dtype (float32 or float64 depending on your OS)
A = A.astype('object')
A[0, 0] = Fraction(2,3)
print(A)
prints
[[Fraction(2, 3) 1.0]
[-2.0 -1.0]]
PS. As user2357112 suggests, you might be better off using sympy
if you wish to use rational numbers. Or, just represent the matrix as a list of lists. There are no speed advantages to using NumPy if your arrays are of object
dtype.
import sympy as sy
A = [[-1., 1.],
[-2., -1.]]
A[0][0] = sy.Rational('2/3')
print(A)
prints
[[2/3, 1.0], [-2.0, -1.0]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With