Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modified the handling of zero and infinity to map to the Riemann sphere. #17

Merged
merged 4 commits into from
Jan 28, 2018
Merged

Modified the handling of zero and infinity to map to the Riemann sphere. #17

merged 4 commits into from
Jan 28, 2018

Conversation

derknorton
Copy link
Contributor

With regards to #5 I took a shot at the option of mapping the complex plane to the Riemann sphere as suggested by @balagge and referencing the wikipedia definition: https://en.wikipedia.org/wiki/Riemann_sphere

The code assumes that there is only one infinity at the north pole and only one zero at the south pole. I added Complex.INFINITY = new Complex(Infinity, Infinity) as the singular infinity pole (the Complex.ZERO already exists. The way to think about this is that each pole collapses to a scaler value rather than a complex value. The operations are well defined mathematically and I added test cases for all of the important ones involving zero and infinity documented at the wikipedia site: https://en.wikipedia.org/wiki/Riemann_sphere#Arithmetic_operations . I also fixed the test cases that were incorrect according to the Riemann mapping.

Take a look at it and see if it still meets the needs of most users. The size of the code did not grow too much and I was able to add quite a few "short circuits" for the Riemann cases to help speed up processing. Thoughts?

…se() function return the value of P. The parse() function is now only called in the constructor Complex(a, b) and all other calls to parse() have been replaced with 'var z = new Complex(a, b)'. The variable z is used to avoid confusion with the old P global variable. NOTE: I left the test file pointing to the complex.js file instead of the complex.min.js file so that should be changed prior to integration.
…ity at the north pole and a single zero at the south pole. All operations are consistent with the definitions documented here: https://en.wikipedia.org/wiki/Riemann_sphere#Arithmetic_operations
Copy link
Contributor

@harrysarson harrysarson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, have one suggestion

@@ -1238,6 +1317,8 @@
Complex['I'] = new Complex(0, 1);
Complex['PI'] = new Complex(Math.PI, 0);
Complex['E'] = new Complex(Math.E, 0);
Complex['INFINITY'] = new Complex(Infinity, Infinity);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer calling this ComplexInfinity or simliar to make it clear that this is different from the real infinity that people are used to in JavaScript

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose the same could be said for the NAN. But since they are all CAPS and prefixed by the type (Complex.INFINITY and Complex.NAN) I am not sure the clarification is necessary. Doesn't matter to me though...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if ComplexInfinity is more unambiguous, I like Complex.INFINITY and Complex.NAN better, since you would normally use it exactly as "Complex.INFINITY" and so it states already what ComplexInfinity wants to express.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the question is how strongly do you feel about having the uppercase names. People are used to writing NaN rather than NAN so the upper case version may be confusing.

complex.js Outdated
@@ -130,6 +128,8 @@

var parse = function(a, b) {

var P = {'re': 0, 'im': 0};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the P variable be changed to lowercase now that is is no longer a global? Perhaps change it to z to reflect its purpose?

@@ -1238,6 +1317,8 @@
Complex['I'] = new Complex(0, 1);
Complex['PI'] = new Complex(Math.PI, 0);
Complex['E'] = new Complex(Math.E, 0);
Complex['INFINITY'] = new Complex(Infinity, Infinity);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if ComplexInfinity is more unambiguous, I like Complex.INFINITY and Complex.NAN better, since you would normally use it exactly as "Complex.INFINITY" and so it states already what ComplexInfinity wants to express.

@@ -385,7 +447,7 @@ var tests = [{
set: "0-0i",
fn: "pow",
param: 0,
expect: "0"
expect: "1"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the rationale behind "0^0"=1?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as x -> 0, x^x -> 1 could be the reason

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that makes sense. But typically 0^0 is undefined. So 0 wasn't the best option either, but the question is if 0^0 should be defined as 1. I mean, Math.pow(0,0)=1 having it for complex numbers equal to one would make it consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a very good point. It seems like it should be either Complex.ONE or Complex.NAN. The IEEE floating point standard defines it both ways according to wikipedia: https://en.wikipedia.org/wiki/Zero_to_the_power_of_zero#IEEE_floating-point_standard

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say let's go with Complex.ONE with a small note in the readme.

@infusion
Copy link
Collaborator

Besides my small annotations, this looks pretty good to me. @harrysarson What do you think about it in contrast to your previous work towards infinity support?

…is no longer a global variable. Updated the README file to include the new complex constants.
@harrysarson
Copy link
Contributor

harrysarson commented Jan 28, 2018

Yeah, I like having 1 / 0 === RealInfinitiy but the diff for this change does look nicer than #12.

There are some changes in #12 that are still relavant and I can make a seperate PR for those once this is merged/

This was referenced Jan 28, 2018
@harrysarson
Copy link
Contributor

What do we do with tanh etc? Should tanh(Infinity) === 1?

@infusion
Copy link
Collaborator

@harrysarson that would be great, thanks!

Trig functions under Infinity is a whole new topic. Do you know a resource of what the behavior should be, besides tanh(Infinity)= 1?

@infusion infusion merged commit ae9ac3c into rawify:master Jan 28, 2018
@derknorton derknorton deleted the pr/riemann-sphere branch January 28, 2018 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants