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

Add sqrt primitive. #57

Merged
merged 1 commit into from
Nov 2, 2019
Merged

Add sqrt primitive. #57

merged 1 commit into from
Nov 2, 2019

Conversation

ummarikar
Copy link
Collaborator

This adds the sqrt primitive to yksom for Int, BigInt and Double.

@ummarikar
Copy link
Collaborator Author

I require some guidance. I have put the necessary tests for positive numbers but I am unsure of what to do with negative numbers. In Java SOM, sqrt of negative numbers returns "NaN" and I am not sure what the equivalent of that is in yksom after some initial searching in the codebase. Would appreciate some help!

src/lib/vm/val.rs Outdated Show resolved Hide resolved
@ltratt
Copy link
Member

ltratt commented Oct 18, 2019

In Java SOM, sqrt of negative numbers returns "NaN" and I am not sure what the equivalent of that is in yksom after some initial searching in the codebase.

It should probably either produce NaN ("Not A Number") or throw an error. @smarr any thoughts on which? I'm inclined towards the latter, in part because sqrt in C throws an error (rather than producing NaN).

@ltratt ltratt self-assigned this Oct 18, 2019
@ltratt
Copy link
Member

ltratt commented Oct 19, 2019

OK, having taken a quick look at this, I think the correct thing to do (in IEEE 574) is to return NaN, so let's do that (which, conveniently, is what Rust's sqrt does anyway) and add some appropriate tests.

@ummarikar
Copy link
Collaborator Author

Just implemented NaN for negative square roots. Let me know if you want me to squash.

@ummarikar
Copy link
Collaborator Author

ummarikar commented Oct 20, 2019

Removing all the above if statements produced the following error (for Integers):
thread 'main' panicked at 'the square root of a negative is imaginary', /Users/umarmarikar/.cargo/registry/src/github.com-1ecc6299db9ec823/num-integer-0.1.41/src/roots.rs:171:1 note: run with RUST_BACKTRACE=1 environment variable to display a backtrace.
However, the Double tests worked.
Should I keep the if statement in val.rs and integer.rs and remove it in double.rs?

@ltratt
Copy link
Member

ltratt commented Oct 21, 2019

Let's remove the ifs that aren't needed, but we should definitely keep those that are!

@ummarikar
Copy link
Collaborator Author

Done!

@ltratt
Copy link
Member

ltratt commented Oct 22, 2019

Please squash.

@ummarikar
Copy link
Collaborator Author

Squashed

@ltratt
Copy link
Member

ltratt commented Oct 23, 2019

I just realised a problem. If self.val < 0 (for ints or big ints), we need to throw an error, not return a NaN. It's kinda weird if -1.sqrt() returns a double. We'll need tests for that too. We can make a new error (borrowing shamelessly from Python) VMError::DomainError or similar.

@ltratt
Copy link
Member

ltratt commented Oct 27, 2019

If this is ready for rereview, you need to tell me explicitly.

@ummarikar
Copy link
Collaborator Author

If this is ready for rereview, you need to tell me explicitly.

I know, I only just got round to doing a double check now (I've had coursework from my modules recently), and I think there's nothing more I need to do so feel free to take a look!

src/lib/vm/core.rs Outdated Show resolved Hide resolved
@smarr
Copy link
Contributor

smarr commented Oct 27, 2019

I saw this before, and thought it is sensible.

However, triggered by SOM-st/SOM#24, does yksom give the expected results for 4 sqrt, 1 sqrt, and 3 sqrt?

---> 4 sqrt
it = 2
---> 1 sqrt
it = 1
---> 3 sqrt
it = 1.7320508075688772

and:

---> 4 sqrt class
it = Integer
---> 1 sqrt class
it = Integer
---> 3 sqrt class
it = Double

@ltratt
Copy link
Member

ltratt commented Oct 27, 2019

Good point! No, this PR will not produce ints even when it could. I'm not even entirely sure I know the best way to implement this semantically. Obvious possibilities are 1) see if the FP number produced is int-like and if so convert it 2) convert the result to an int, square it, and see if you get the original answer again. I think those two routes will behave subtly different in some edge conditions, though I haven't checked. Any thoughts?

@smarr
Copy link
Contributor

smarr commented Oct 27, 2019

SOM and CSOM do basically the same for the case with an Integer as a receiver.

https://github.com/SOM-st/CSOM/blob/master/src/primitives/Integer.c#L267-L274

https://github.com/SOM-st/som-java/blob/3fab8ac7f34cedbbe15719fc607bceef25343d59/src/som/vmobjects/SInteger.java#L82-L89

Note that 4.0 sqrt class yields a Double.

@smarr
Copy link
Contributor

smarr commented Oct 27, 2019

Ah, and at this point, in the sense of a spec, I wouldn't consider this required behavior...

I think, I'd need to find the people who implemented that originally and get their reasoning, i.e., do some historical digging.

@ltratt
Copy link
Member

ltratt commented Oct 27, 2019

https://github.com/SOM-st/CSOM/blob/master/src/primitives/Integer.c#L267-L274

OK, so that's option #1 of the two I suggested. It's a reasonable enough definition, at least from this PR's perspective. @ummarikar hopefully that gives you a bit of feedback for how to improve the PR a bit?

Ah, and at this point, in the sense of a spec, I wouldn't consider this required behavior...

Fair enough. I think it's not a bad idea to implement it similarly though -- if nothing else, reducing the points of divergence (as far as possible) to only clear bugs will probably make everybody's life easier!

@ummarikar
Copy link
Collaborator Author

https://github.com/SOM-st/CSOM/blob/master/src/primitives/Integer.c#L267-L274

OK, so that's option #1 of the two I suggested. It's a reasonable enough definition, at least from this PR's perspective. @ummarikar hopefully that gives you a bit of feedback for how to improve the PR a bit?

Ah, and at this point, in the sense of a spec, I wouldn't consider this required behavior...

Fair enough. I think it's not a bad idea to implement it similarly though -- if nothing else, reducing the points of divergence (as far as possible) to only clear bugs will probably make everybody's life easier!

Yes, this is great I'll implement it asap. Thanks for the feedback!

@ummarikar
Copy link
Collaborator Author

ummarikar commented Oct 27, 2019

Just did some playing around with yksom. It has the following behaviour:

---> 4 sqrt class
it = Integer
---> 1 sqrt class
it = Integer
---> 3 sqrt class
it = Integer

I'll make sure that Integer sqrt produces a Double if the result is not a whole number.

@ltratt
Copy link
Member

ltratt commented Oct 27, 2019

I'll make sure that Integer sqrt produces a Double if the result is not a whole number.

The links Stefan sent to other SOM's might give you a good pointer for how to go about this.

@ummarikar
Copy link
Collaborator Author

Added some code to val.rs which ensures that a Double is returned when the square root of an Integer is not a whole number. I was not sure if you want me to change the implementation of sqrt for BigInts when the result is not a whole number. The current implementation in Java SOM is to return an error in this case.

@ummarikar
Copy link
Collaborator Author

I also added an extra test case for "3 sqrt".

@ltratt
Copy link
Member

ltratt commented Oct 27, 2019

We need to make sure both Ints and ArbInts have the same behaviour (from the SOM user's perspective they're one and the same).

@ltratt
Copy link
Member

ltratt commented Oct 27, 2019

I think we also need checks along the lines of:

16 sqrt class println.

to make sure that things are printing Integer / Double as appropriate.

to check that

@ummarikar
Copy link
Collaborator Author

Sure I'll start that now.

lang_tests/int29.som Outdated Show resolved Hide resolved
@ummarikar
Copy link
Collaborator Author

All done.

@ltratt
Copy link
Member

ltratt commented Nov 1, 2019

Please squash.

This adds the sqrt primitive to yksom for Int, BigInt and Double.
@ummarikar
Copy link
Collaborator Author

Squashed.

@ltratt
Copy link
Member

ltratt commented Nov 2, 2019

bors r+

bors bot added a commit that referenced this pull request Nov 2, 2019
57: Add sqrt primitive. r=ltratt a=ummarikar

This adds the sqrt primitive to yksom for Int, BigInt and Double.

Co-authored-by: K1630549 <[email protected]>
@bors
Copy link
Contributor

bors bot commented Nov 2, 2019

Build succeeded

@bors bors bot merged commit f6c30e0 into softdevteam:master Nov 2, 2019
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