0

Suppose I have an expression involving the decimal module where I want to input multiple values and get multiple values out.

a=np.array([1,2,3])
b=np.array([4,5,6])
A=a.astype(object)
B=b.astype(object)

getcontext().prec = 100
x=Decimal(A+B)

This raises an error since Decimal is incompatible with numpy arrays.

How can I pass multiple values through a Decimal expression and get multiple values out in such a way that I could easily convert the outputs to a float and then put them in a numpy array?

The reason I would want this is that a certain calculation involves A+B being calculated incorrectly as a float but once Decimal(A+B) is calculated, the resulting output can be converted to a float and cause no further difficulties in the calculation.

EDIT: I have been developing a 'cheat' method but I don't know if it has legs:

a=np.array([1,2,3])
b=np.array([4,5,6])
A=a.astype(object)
B=b.astype(object)

getcontext().prec = 100
for i in range (0,2):
    x=Decimal(A[i]+B[i])
    print(x)

Key here is to indent print(x), this prints 5 7 9. Failing a true solution to the above problem, is there a way of converting 5 7 9 to np.array([5,7,9]). (Maybe by exporting as csv file and importing into Python again?)

  • What are you expecting (or desiring) `x` to end up containing? – martineau May 05 '20 at 17:14
  • So in an ideal world x would be a numpy array [5,7,9]. Obviously I know I can't do that, but I would like the get the values Decimal(5),Decimal(7),Decimal(9) all out in some format that I could eventually convert them to floats and then arrive at the numpy array. – MysteriousBrit May 05 '20 at 17:18
  • I doubt there's any way to do this short of writing your own conversion functions. – martineau May 05 '20 at 17:43
  • Hmm...I was worried that might be the case. I have a cheat way I'm developing at the moment. I'll edit question above to see if it might be fruitful – MysteriousBrit May 05 '20 at 17:52
  • That's perfect! I've just checked and I can convert the output to a float. Really thanks @martineau . Happy to accept that as the answer! – MysteriousBrit May 05 '20 at 18:14

1 Answers1

0

I think you could do it manually like this:

r = np.array(tuple(Decimal(x+y) for x, y in zip(A, B)), np.float64)
print(r)

Output:

[5. 7. 9.]
martineau
  • 119,623
  • 25
  • 170
  • 301
  • Thanks @martineau . The above answer allows me to create functions using decimal.Decimal with numpy arrays as both inputs and outputs. – MysteriousBrit May 05 '20 at 18:24
  • Yes, it would, but it's also kind of defeating the main purpose of `numpy` which is to vectorize numerical processing and make it faster. Here it's just being used as a storage-container (and introducing additional overhead due to the conversions that slows everything down). – martineau May 05 '20 at 18:32
  • Ah so the cost here is speed and memory - makes sense – MysteriousBrit May 05 '20 at 18:45
  • It's more common (and desirable) to trade speed _for_ memory — use more memory to make something faster. This is just using more memory _and_ making things slower. Why are you using `numpy`? Converting back and forth between `Decimal` and `float` is also defeating the main point of using the `decimal` module. – martineau May 05 '20 at 18:48
  • Essentially the calculations work except at very specific points. The alternative to calculate everything correctly involves replacing `matmul` functions with `dot`. This leads to lack of memory errors. The problem isn't serious enough to completely overhaul the code - so the compromise is being made as an 'optional patch'. It's certainly not pretty! – MysteriousBrit May 06 '20 at 00:14
  • I suggest you check-out the [`mpmath`](http://mpmath.org/doc/current/) module which may provide another option and might be a better tradeoff (it supports vector and matrix operations/functions). – martineau May 06 '20 at 00:24