Created on 2010-11-28 15:19 by Retro, last changed 2011-11-21 20:12 by gvanrossum. This issue is now closed.

Messages (60)

msg122662 - (view) Author: Boštjan Mejak (Retro) Date: 2010-11-28 15:19

In Python, the letter 'j' denotes the imaginary unit. It would be great if we would follow mathematics in this regard and let the imaginary unit be denoted with an 'i'.

msg122663 - (view) Author: Michael Foord (michael.foord) * Date: 2010-11-28 15:21

We follow engineering which uses j. (I was about to close this as wontfix but Antoine is particularly keen that Mark deals with this issue...)

msg122669 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-11-28 16:06

Glad to oblige. :-)

msg122672 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-11-28 16:11

Just to add my own thoughts: 'j' for *a* (not *the* </pedantry>) square root of -1 has, as Michael points out, a history of use in engineering (particularly electrical engineering) and physics. Personally, I would have preferred 'i' to 'j' here, but changing it now would cause (IMO) gratuitous breakage. It really doesn't seem a big enough issue to be worth making a fuss about.

msg122722 - (view) Author: Boštjan Mejak (Retro) Date: 2010-11-28 20:30

"The Python programming language also uses j to denote the imaginary unit. MATLAB associates both i and j with the imaginary unit." -Wikipedia<http://en.wikipedia.org/wiki/Imaginary_unit#Alternative_notations> It would be a welcome feature in Python if the programming language would, like MATLAB, associate both i and j with the imaginary unit.

msg122728 - (view) Author: Alexander Belopolsky (belopolsky) * Date: 2010-11-28 20:49

Why not allow complex('1i')? (Tongue in cheek: I am really looking for arguments against lax parsing in number builtins. See issue 10557.)

msg122729 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-11-28 20:55

> It would be a welcome feature in Python if the programming language > would, like MATLAB, associate both i and j with the imaginary unit. I suggest taking this to the python-ideas mailing list. A working patch might increase the idea's chances.

msg122730 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-11-28 20:58

> Why not allow complex('1i')? Indeed, if 4i were permitted as an imaginary literal, I'd expect to allow complex('3 + 4i') as well. (And possible just plain complex('i') too, since complex('j') is currently allowed. Grr.)

msg122731 - (view) Author: Alexander Belopolsky (belopolsky) * Date: 2010-11-28 21:03

On Sun, Nov 28, 2010 at 3:58 PM, Mark Dickinson <report@bugs.python.org> wrote: .. > I'd expect to allow complex('3 + 4i') as well. And with spaces surrounding '+' too.

msg122732 - (view) Author: Boštjan Mejak (Retro) Date: 2010-11-28 21:14

It would be great if the feature of having both j and i would exist in the interpreter core, as well as the built-in function complex() to accept i.

msg122733 - (view) Author: Antoine Pitrou (pitrou) * Date: 2010-11-28 21:17

There should be an environment variable to make the symbol settable. $ PYTHONIMAGINARYSYMBOL=i python -c "import cmath; print(cmath.sqrt(-1))" 1i

msg122734 - (view) Author: Antoine Pitrou (pitrou) * Date: 2010-11-28 21:17

(and perhaps a ResourceWarning if you choose something different from i and j)

msg123101 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-02 18:56

The imaginary unit 'i' should be equvivalent to the imaginary unit 'j'. The imaginary unit, however, should be used consistently in the source code.

msg123102 - (view) Author: Raymond Hettinger (rhettinger) * Date: 2010-12-02 19:04

If this change were important, the numpy/scipy guys would have requested it long ago. Any possible benefit would be slight and not at all worth the disruption. s.replace('j', 'i')

msg123105 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-12-02 19:40

> There should be an environment variable to make the symbol settable. That could work; it's a bit late to do this in 3.2, though. How about the following transition strategy for the complex output. Python 3.3: Introduce PYTHONIMAGINARYSYMBOL environment variable (and possibly also a related command-line option to the interpreter?). Python 3.4: Show a warning on startup if this environment variable isn't used. Python 3.5: Make the environment variable mandatory. Python 3.6: Make the environment variable optional again, but this time with the default output being 'i' rather than 'j'. Python 3.7: Deprecate use of PYTHONIMAGINARYSYMBOL. (Warning on startup if it's set.) Python 3.8: Error on startup if PYTHONIMAGINARYSYMBOL is set. Python 3.9: Go back to ignoring PYTHONIMAGINARYSYMBOL. I'm sure we could find a compatible transition strategy for the complex *inputs*: (3.3: accept both 'i' and 'j'; 3.6: warn about 'j' usage; 3.8 remove acceptance of 'j' on input).

msg123106 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-02 19:46

That is acceptable, but way to slow for the 'j' imaginary unit to become extinct. It should happen sooner.

msg123108 - (view) Author: Georg Brandl (georg.brandl) * Date: 2010-12-02 20:30

We also should consider a good roadmap to account for the eventual support of quaternions in the language syntax. Since the conventional mathematical symbols for the additional imaginary units of quaternions are j and k, confusion is bound to happen. My preferred solution is to limit PYTHONIMAGINARYSYMBOL values to "i", "j" or "k" in Python 3.4. The two additional imaginary unit symbols would then be a cyclic permutation of i,j,k, viz. for PYTHONIMAGINARYSYMBOL=j, the units are k and i. This deterministic approach has the advantage that migration of code from one imaginary symbol to another is as easy as: sed -e 's/k/l/' -e 's/j/k/' -e 's/i/j/' -e 's/l/i/' provided that you restrict yourself not to use the characters i, j, k or l in identifiers, keywords or strings in the source code.

msg123110 - (view) Author: Antoine Pitrou (pitrou) * Date: 2010-12-02 20:41

> Since the conventional mathematical symbols for the additional > imaginary units of quaternions are j and k, confusion is bound to > happen. > > My preferred solution is to limit PYTHONIMAGINARYSYMBOL values to "i", > "j" or "k" in Python 3.4. The two additional imaginary unit symbols > would then be a cyclic permutation of i,j,k, viz. for > PYTHONIMAGINARYSYMBOL=j, the units are k and i. Can we consider an environment variable to change the direction of the permutation, e.g. PYTHONIMAGINARYPERMUTATIONDIR=-1? Otherwise +11j from me.

msg123111 - (view) Author: Raymond Hettinger (rhettinger) * Date: 2010-12-02 20:41

Since we have two distinct user groups (engineers and everyone else), it's clear that we should fork Python. That would let each group work with their on most-natural-representation and it would prevent unnecessary configuration challenges. Benjamin, could you please start a new branch and fork the website into python.i.org and python.j.org.

msg123112 - (view) Author: Brian Curtin (brian.curtin) * Date: 2010-12-02 20:45

Will PYTHONIMAGINARYPERMUTATIONDIR accept imaginary numbers? If so, we will also need PYTHONIMAGINARYPERMUTATIONDIRIMAGINARYIDENTIFIER.

msg123114 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-02 20:57

How did you implement the letter 'j' as the imaginary unit? Can you now implement the letter 'i' to act as an imaginary unit? Is that possible? If it's possible in MATLAB, why not have both 'j' and 'i' in Python as well?

msg123115 - (view) Author: Georg Brandl (georg.brandl) * Date: 2010-12-02 21:06

I heard that MathWorks has a patent on METHOD AND APPARATUS FOR IMAGINATORIAL FREEDOM, so if that's true we might not be allowed to implement it.

msg123117 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-02 21:13

"In electrical engineering<http://en.wikipedia.org/wiki/Electrical_engineering> and related fields, the imaginary unit is often denoted by *j* to avoid confusion with electrical current<http://en.wikipedia.org/wiki/Current_(electricity)> as a function of time, traditionally denoted by *i*(*t*) or just *i*." -Wikipedia Does Python have to deal with electrical current as a function of time to associate j with the imaginary unit and not i?

msg123118 - (view) Author: Brian Curtin (brian.curtin) * Date: 2010-12-02 21:14

yes

msg123119 - (view) Author: Georg Brandl (georg.brandl) * Date: 2010-12-02 21:16

Sure. I have personally written software where i denotes, in effect, an electrical current.

msg123120 - (view) Author: Raymond Hettinger (rhettinger) * Date: 2010-12-02 21:21

> Can you now implement the letter 'i' to act as an > imaginary unit? Is that possible? Yes, it's possible; however, the developers do not think it is worthwhile. > If it's possible in MATLAB, why not have both 'j' and 'i' > in Python as well? Python does some things differently that MATLAB. One design choice is to avoid global configurations (such as number of places displayed in a float) because modules written by different people make make different assumptions or may compete for a preferred setting. Let's try to end this thread now. It's a bit of no-win situtation. None of the core devs see enough possible benefit to warrant the disruption it would cause. Years of Python being used in the scientific community has shown that the current use of 'j' has not been a problem.

Mark Dickinson wrote: > > Mark Dickinson <dickinsm@gmail.com> added the comment: > >> There should be an environment variable to make the symbol settable. > > That could work; it's a bit late to do this in 3.2, though. How about the following transition strategy for the complex output. > > Python 3.3: Introduce PYTHONIMAGINARYSYMBOL environment variable (and possibly also a related command-line option to the interpreter?). > > Python 3.4: Show a warning on startup if this environment variable isn't used. > > Python 3.5: Make the environment variable mandatory. > > Python 3.6: Make the environment variable optional again, but this time with the default output being 'i' rather than 'j'. > > Python 3.7: Deprecate use of PYTHONIMAGINARYSYMBOL. (Warning on startup if it's set.) > > Python 3.8: Error on startup if PYTHONIMAGINARYSYMBOL is set. > > Python 3.9: Go back to ignoring PYTHONIMAGINARYSYMBOL. > > I'm sure we could find a compatible transition strategy for the complex *inputs*: (3.3: accept both 'i' and 'j'; 3.6: warn about 'j' usage; 3.8 remove acceptance of 'j' on input). Hmm, what calendar are you using ? April 1st is still a few months away on the Gregorian one and even the Julian calendar isn't that far off yet :-) Why not simply support both for number constructors (and stick with 'j' for the language spec) ?

msg123122 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-12-02 21:33

In all seriousness, the idea of accepting both 'i' and 'j' in complex() isn't horrible. I'm personally -0.small on it, mostly because it seems likely to lead to more objections about the complex str() and repr() *output* containing 'j's. I still think python-ideas would be a more appropriate place for that discussion, though.

Mark Dickinson wrote: > > Mark Dickinson <dickinsm@gmail.com> added the comment: > > In all seriousness, the idea of accepting both 'i' and 'j' in complex() isn't horrible. I'm personally -0.small on it, mostly because it seems likely to lead to more objections about the complex str() and repr() *output* containing 'j's. I still think python-ideas would be a more appropriate place for that discussion, though. I think this falls under a "locale" problem of some sort... engineers like 'j', mathematician prefer 'i'. Personally, I think it's more important to be able to read scientific data easily without too many problems, then to be able to write the processed data in exactly the same way it was read. When formatting complex numbers, you have the issues of whether to include spaces, parens, 'i' or 'j', so this is better left to a application space function to deal with, IMHO. I would prefer to have str() and repr() always use the parens and j notation - it makes recognizing complex numbers easier, e.g. compare (1+0j) >>> 0+1j 1j >>> 11 11 to (1+0j) >>> 0+1j (0+1j) >>> 11 11 (but I guess that another problem)

msg123131 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-12-02 22:08

> Personally, I think it's more important to be able to read > scientific data easily without too many problems, then to be > able to write the processed data in exactly the same way it > was read. I wonder whether there are many examples where scientific data is written in a form that Python's complex() constructor couldn't currently read, but would be able to read if it accepted 'i' in place of 'j'. My (wild) guess would be that, in the cases where the data isn't stored in binary form anyway, complex numbers are written simply as pairs of floats.

msg123134 - (view) Author: Georg Brandl (georg.brandl) * Date: 2010-12-02 22:15

That would be a good question for a numpy/scipy-related mailing list, I guess.

msg123135 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-12-02 22:29

Maybe we need a complex analog to datetime.strptime: complex.strpcx('(3 + 4i)', '(%R + %Ii)') -> 3 + 4j

msg123140 - (view) Author: Antoine Pitrou (pitrou) * Date: 2010-12-02 22:42

Le jeudi 02 décembre 2010 à 22:29 +0000, Mark Dickinson a écrit : > Mark Dickinson <dickinsm@gmail.com> added the comment: > > Maybe we need a complex analog to datetime.strptime: > > complex.strpcx('(3 + 4i)', '(%R + %Ii)') -> 3 + 4j How about '3 + 4i'.transform('complex')?

msg123146 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-02 23:54

(7.8064-6j) According to PEP 8, the output in our example should be with spaces surrounding the subtraction operator, like this: >>> (1 + 2.56j) * (-1 - 3.44j) (7.8064 - 6j)

msg123179 - (view) Author: Éric Araujo (eric.araujo) * Date: 2010-12-03 04:49

Whether 1+2j is a literal or an expression is debatable. I think +1 is an expression but 1+2j is a literal; neither should have a space. I’m not sure the language reference and the actual implementation are in agreement here (I have peephole optimizations in mind).

msg123188 - (view) Author: Alexander Belopolsky (belopolsky) * Date: 2010-12-03 05:34

On Thu, Dec 2, 2010 at 11:49 PM, Éric Araujo <report@bugs.python.org> wrote: .. > Whether 1+2j is a literal or an expression is debatable. > I think +1 is an expression but 1+2j is a literal; neither should have a space. With respect to implementation there is no debate: [TokenInfo(type=57 (ENCODING), string='utf-8', start=(0, 0), end=(0, 0), line=''), TokenInfo(type=2 (NUMBER), string='1', start=(1, 0), end=(1, 1), line='1+1j'), TokenInfo(type=53 (OP), string='+', start=(1, 1), end=(1, 2), line='1+1j'), TokenInfo(type=2 (NUMBER), string='1j', start=(1, 2), end=(1, 4), line='1+1j'), TokenInfo(type=0 (ENDMARKER), string='', start=(2, 0), end=(2, 0), line='')] [TokenInfo(type=57 (ENCODING), string='utf-8', start=(0, 0), end=(0, 0), line=''), TokenInfo(type=53 (OP), string='-', start=(1, 0), end=(1, 1), line='-1'), TokenInfo(type=2 (NUMBER), string='1', start=(1, 1), end=(1, 2), line='-1'), TokenInfo(type=0 (ENDMARKER), string='', start=(2, 0), end=(2, 0), line='')] (Who designed the tokenize interface, btw? I took me 3 tries to come up with the incantation above.) > > I’m not sure the language reference and the actual implementation are in agreement here > (I have peephole optimizations in mind). Literals are atomic to the tokenizer. AST processes a stream of tokens. Peephole optimizations are irrelevant because these are hacks that operate on the bytecode when the lexical structure is all but forgotten.

msg123189 - (view) Author: Alexander Belopolsky (belopolsky) * Date: 2010-12-03 05:35

And of course, roundup ate my work. The tokenize incantation was >>> pprint(list(tokenize(iter([b'1+1j']).__next__)))

msg123200 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-12-03 08:00

> Whether 1+2j is a literal or an expression is debatable. Really? I can't imagine what basis you'd have for calling either 1+2j or +1 a literal.

msg123208 - (view) Author: Georg Brandl (georg.brandl) * Date: 2010-12-03 08:53

An imaginary basis maybe?

msg123212 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-03 09:26

The result of 1 + 2j cannot be further broken down, so the result stays as 1 + 2j (note the spaces!). (1+2j) (1 + 2j) Following PEP 8 in this regard is also needed. Abandon the request of adding the i unit and rather fix this spacing issue. The complex() built-in function should also be fixed to add spaces around operators.

Mark Dickinson wrote: > > Mark Dickinson <dickinsm@gmail.com> added the comment: > > Maybe we need a complex analog to datetime.strptime: > > complex.strpcx('(3 + 4i)', '(%R + %Ii)') -> 3 + 4j That's a good idea. Perhaps we could also add a .strfcx() to do the formatting in much the same way.

msg123219 - (view) Author: Robert Lehmann (lehmannro) * Date: 2010-12-03 09:45

> I wonder whether there are many examples where scientific data is written in a form that Python's complex() constructor couldn't currently read, but would be able to read if it accepted 'i' in place of 'j'. I could not reproduce widespread real world issues with the syntax as it stands using Google Code Search (a mere 4 unique hits). http://goo.gl/sqMhY

msg123220 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2010-12-03 09:59

Thanks for that, Robert. Actually, I find those few results quite convincing as evidence that it would be useful to support 'i' (and 'I') on input.

msg123235 - (view) Author: Éric Araujo (eric.araujo) * Date: 2010-12-03 12:45

> I can't imagine what basis you'd have for calling either 1+2j or +1 a literal. Poor understanding of the parser/tokenizer/formal grammar.

msg123245 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-03 13:41

Please make the tokenizer surround spaces around operators. So the output would be like in the example below: (1 + 2j) (1 + 2j)

msg123256 - (view) Author: Adam Byrtek (adambyrtek) Date: 2010-12-03 16:18

What happened with "there should be one-- and preferably only one --obvious way to do it"?

msg123269 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-03 16:57

Indeed. There should be spaces around all the operators. Even in my posted example.

msg123272 - (view) Author: Alexander Belopolsky (belopolsky) * Date: 2010-12-03 17:18

On Fri, Dec 3, 2010 at 11:57 AM, Boštjan Mejak <report@bugs.python.org> wrote: .. > Indeed. There should be spaces around all the operators. Even in my posted > example. Aim higher: we obviously want Python output look beautiful in print, so operands should be surrounded by U+2009 (THIN SPACE).

msg123274 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-03 17:22

Alexander, is it possible to make an output like (1+2j) be printed as (1 + 2j). Also, why is the result put in parens?

msg123276 - (view) Author: Alexander Belopolsky (belopolsky) * Date: 2010-12-03 18:03

> Alexander, is it possible to make an output like (1+2j) > be printed as (1 + 2j). Sure, and 'j' can be highlighted in red, but this is a job for a front-end or a custom display hook, not core python. You may want to take a look at ipython. > Also, why is the result put in parens? There was a historical reason for that, but I don't remember it now. You may find the answer in the tracker, svn log, or python-dev archives. It may not have been obvious, but most of the comments here including mine were not serious even when they did not include smileys. Nothing will happen here. Time to move on.

msg123279 - (view) Author: Eric Pruitt (ericpruitt) * Date: 2010-12-03 18:21

> Also, why is the result put in parens? Without them, something like 'eval("100 * " + repr(imaginary))' would not work properly.

msg123281 - (view) Author: Boštjan Mejak (Retro) Date: 2010-12-03 19:13

Parens are okay then. Still, put spaces around operators. If 1 + 2j let the output be (1 + 2j) Please!!!

msg148010 - (view) Author: Boštjan Mejak (Retro) Date: 2011-11-20 21:33

What's up with that now? Any interests in changing the imaginary unit from "j" to "i" ?

msg148011 - (view) Author: Boštjan Mejak (Retro) Date: 2011-11-20 21:37

Come on, let's do this.

msg148015 - (view) Author: Nick Coghlan (ncoghlan) * Date: 2011-11-20 23:51

While this thread was amusing to read, *changing* Python from the engineering notation to mathematical notation for imaginary numbers is not going to happen. 'i' has ambiguity problems relative to '1' and 'l' in too many fonts - 'j', on the other hand, almost always uses a visually distinct glyph. And whether 'i' or 'j' seems more natural to you will depend on whether or not you have an electrical engineering background (as noted earlier in the thread, 'i' refers to current in electrical engineering). If you care about the precise formatting of a complex number, write your own formatting function rather than relying on the exact format produced by "repr(num)". Having an alternate constructor for complex objects that was more forgiving about 'i' vs 'j' also doesn't offer a huge benefit over the simple "x = complex(arg.replace('i', 'j')". So while I have some sympathy for mathematicians that are frustrated by having to train their fingers to hit 'j' instead of 'i', that's not a good enough reason to change the language syntax or the behaviour of the complex() builtin. (See also http://www.boredomandlaziness.org/2011/02/status-quo-wins-stalemate.html)

msg148071 - (view) Author: Boštjan Mejak (Retro) Date: 2011-11-21 19:20

It's stupid that the imaginary unit in Python is denoted by a "j" just for ambiguity reasons that "i" can be mistaken with a "1" or an "l". It's true that "1" and "l" can look the same in some fonts, but that is *certainly not true* for the small letter "i". Just fix the "j" into an "i" already.

msg148072 - (view) Author: Boštjan Mejak (Retro) Date: 2011-11-21 19:25

Please fix this in Python 3.3 and don't forget to fix the complex() function/method as well.

msg148073 - (view) Author: Brian Curtin (brian.curtin) * Date: 2011-11-21 19:26

Please stop re-opening this thread. The reasons it will not be fixed have been laid out.

msg148081 - (view) Author: Eric Snow (eric.snow) * Date: 2011-11-21 19:54

@brian.curtin: +1 @Retro: as noted in #10621, please take this to python-ideas@python.org

msg148083 - (view) Author: Guido van Rossum (gvanrossum) * Date: 2011-11-21 20:12