# [SciPy-dev] New in fastumath ~ (means conjugate on floats and complex numbers)

eric eric at scipy.org
Tue Feb 26 14:07:05 CST 2002

```> On Sunday 24 February 2002 01:24 am, you wrote:
> > I finally realized that with a simple change we can use the unary operator
> > on floats and complex numbers to mean complex conjugation.
> >
> > I've made the simple change in the CVS version of fastumath.
> >
> > So, in scipy complex-conjugation is as simple as
> >
> > ~a
> >
> > if a is a complex number (or a float).
> >
> > The only problem is that if a is an integer it still means bitwise
> > inversion.
> >
> > Is the added convenience worth the possible confusion?  The problem is that
> > complex conjugation happens all the time, but bitwise inversion rarely.
>
> So, what if we made ~ consistently complex conjugation and eliminated the
> confusion.  The invert would still be available as a function call.
>
> We could also make changes to any of the other symbols as well while we are
> at it if the demand is there.  We can do this without making any changes to
> Numeric as well.
>
> Let me know.  If no one likes the idea but likes writing conjugate(myarray)
> everywhere then I'll back out the changes.

I'm not so fond of conjugate(myarray) and would rather use ~ also, but I can't
see a safe way to do it in numerical code without changing Python itself.  My
view is that numerical operations should work with similar behavior on both
arrays and scalars and should produce un-ambiguous results.  I also do not think
we should make any changes that affect standard Python code (I don't mind
changes to Numeric's behavior though when it is appropriate).  The following set
of examples illustrates the problems of mixing types, etc:

>>> def conj_test(a,b):
...    return ~a + ~b
...

# Try it with two integers
>>> conj_test(1,1)
-4

# Now with two complex values
>>> conj_test(1+0j,1+0j)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in conj_test
TypeError: bad operand type for unary ~

# now try an array -- this produces the results we want
>>> a=array((1+0j))
>>> conj_test(a,a)
(2+0j)

# but mixing an array with an integer returns bogus results
>>> conj_test(a,1)
(-1+0j)

# and mixing with a scalar complex fails.
>>> conj_test(a,1+0j)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in conj_test
TypeError: bad operand type for unary ~

It might be possible to overload the ~ operator in Python2.2 for complex values
so that it worked correctly (I haven't looked into the new type/class stuff
much), but if we did, it is effectively a language change to Python.  In the
complex number arena, I don't think it would break much code, but it does have
that potential.  We need to think long and hard about such decisions and would
do better to lobby Guido et al. about such a change (I sorely want a __cmp__ for
complex numbers to work with some default behavior).

But even if we got it fixed for complex scalars, the fact that conj_test(1,1)
would return completely different results than conj_test(1+0j,1+0j) is a show
stopper to me.  I'd be all for ~ universally meaning conjugate, but its been in
the language for to long for this to happen.

Could we shorten the name to conj()?  Its not as good as ~, but it does cut down
on typing and is obvious to those who would use it.

eric

```