cjrh / misu

High-speed physical quantities and dimensions in Python
BSD 2-Clause "Simplified" License
15 stars 6 forks source link

complex number support #9

Open twmr opened 8 years ago

twmr commented 8 years ago

It is not possible to define quantites of complex numbers:

(3+4j) * misu.km

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-76a72fb11263> in <module>()
----> 1 (3+4j)* misu.km

/home/thomas/gitrepos/misu/misu/engine.pyx in misu.engine.Quantity.__mul__ (misu/engine.c:11569)()
    450             return ansn
    451         else:
--> 452             xq = assertQuantity(x)
    453             yq = assertQuantity(y)
    454             ans = Quantity.__new__(Quantity, xq.magnitude * yq.magnitude)

/home/thomas/gitrepos/misu/misu/engine.pyx in misu.engine.assertQuantity (misu/engine.c:2791)()
     83         return x
     84     else:
---> 85         return Quantity.__new__(Quantity, x)
     86 
     87 

/home/thomas/gitrepos/misu/misu/engine.pyx in misu.engine.Quantity.__cinit__ (misu/engine.c:7829)()
    234     __array_priority__ = 20.0
    235 
--> 236     def __cinit__(self, double magnitude):
    237         self.magnitude = magnitude
    238         #self.stddev = 0

TypeError: can't convert complex to float
cjrh commented 8 years ago

Good catch. The C data type for magnitude is double, that's why.

My first thought is to create another specialised subclass just like the one we have for Numpy arrays, but on the other hand, I'm also wondering how often the need for complex numbers will come up?

twmr commented 8 years ago

I need it quite often. For example, if you are working in a 2D space and can represent your vectors as complex numbers.

cjrh commented 8 years ago

I don't suppose you would consider taking a crack at implementing a "QuantityComplex", in a similar way to how QuantityNP has been implemented here?

https://github.com/cjrh/misu/blob/master/misu/engine.pyx#L582

Further up in the file, the Quantity class is the main Cython class for "quantity" objects. The QuantityNP class detects and upgrades lone Quantity instances when they are combined in operations like __mul__ and so on. I'd imagine that the as-yet nonexistant QuantityComplex would work in a similar way, i.e., it would also detect and upgrade lone Quantity instances into QuantityComplex instances inside the operator overloads.

A tricky problem will be: how to deal with this type of coercion inside QuantityNP? It turns out that there is indeed a complex dtype in Numpy, so I guess we could coerce QuantityComplex into an also as-yet nonexistant QuantityComplexNP in the same way we currently coerce Quantity into QuantityNP.

The design of the current code in engine.pyx might seem very odd, but the reason it is set up in the way it has been is all because of speed. So going forward with these types of changes, I'd want to make sure that we keep control of that. (This is also the reason I don't use Decimal for the magnitude, for example).

I really do need to work on misu again sometime. I still want to add error propagation, for example, but I just haven't had time.

twmr commented 8 years ago

I will play with misu in the coming days and see if it is possible to fully replace python-quantities in the codebase of the company I work with, since python-quantities is so slow and we have lots of quantities in our codebase.

Since, I don't think that its too costly, I'll try to implement support for complex scalars.

Great project!

cjrh commented 8 years ago

Awesome, thanks. As you work, add tests too. Tests are enormously valuable.