1

I'd like to change a 3D array of integers into a SymPy matrix of rationals. I know that I should use Sympy (Rational and Matrix) but I don't know how to do it.

For example,

[[[2, 1], [1, 3], [3, 2]], [[4, 3], [5, 2], [0, 1]]]

should become

2 1/3 3/2
4/3 5/2 0 

A Picture of how it should look:

Wanted result image

colidyre
  • 4,170
  • 12
  • 37
  • 53
LOL
  • 29
  • 6

1 Answers1

0

A convenient way is to create a matrix from a function as follows:

from sympy import Matrix, S
a = [[[2, 1], [1, 3], [3, 2]], [[4, 3], [5, 2], [0, 1]]]
m, n = len(a), len(a[0])
b = Matrix(m, n, lambda i, j: S(a[i][j][0])/a[i][j][1])

The above is assuming the array is a nested Python list. If it was a NumPy 3D array, one can do

from sympy import Matrix, S
import numpy as np
a = np.array([[[2, 1], [1, 3], [3, 2]], [[4, 3], [5, 2], [0, 1]]])
m, n, _ = a.shape
b = Matrix(m, n, lambda i, j: S(a[i, j, 0])/a[i, j, 1])

Note about S(x)/y versus Rational(x, y): the former is division preceded by converting x into a SymPy object. (See SymPy numbers.) This makes a rational out of any kind of integer-looking inputs. Rational(x, y) is a direct construction of a Rational object, which is fine with Python integers as inputs but has an issue with np.int64 datatype. For this reason, Rational(a[i, j, 0], a[i, j, 1]) would not work in the second snippet. (Possibly a SymPy bug.)

  • I have a such fault: unsupported operand type(s) for /: 'Integer' and 'str' – LOL Apr 17 '18 at 20:41
  • So your input array is read as _strings_. This means you need to apply S to both numerator and denominator: `S(a[i, j, 0])/S(a[i, j, 1])` –  Apr 17 '18 at 20:54
  • I have problem. I'd like to change this matrix for 3D matrix now. but now S(a[i, j, 0])/S(a[i, j, 1]) is how one object. How set it – LOL Apr 23 '18 at 10:38