-
Notifications
You must be signed in to change notification settings - Fork 70
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 support for tangent function #231
base: master
Are you sure you want to change the base?
Conversation
Hello @mrkn, anything I should do to this PR to improve it? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rhannequin Thank you for your cooperation. I left some comments. Could you please check them?
test/bigdecimal/test_bigmath.rb
Outdated
assert_in_delta(0.0, tan(BigDecimal("0.0"), N)) | ||
assert_in_delta(0.0, tan(PI(N), N)) | ||
assert_in_delta(1.0, tan(PI(N) / 4, N)) | ||
assert_in_delta(Math.sqrt(3.0), tan(PI(N) / 3, N)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use BigMath.sqrt(BigDecimal(3), N)
instead of Math.sqrt(3.0)
.
Moreover, I guess we need to use assert_equal
instead of assert_in_delta
for all the assertions in this test method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I think we must replace assert_in_delta
with assert_equal
in all the other test methods, but they are out of this PR's target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to check the 10*N
-digit case in addition to the N
-digit case for
assert_in_delta(Math.sqrt(3.0), tan(PI(N) / 3, N)) | |
assert_in_delta(Math.sqrt(3.0), tan(PI(N) / 3, N)) | |
assert_equal(sqrt(BigDecimal(3), 10*N), tan(PI(10*N) / 3, 10*N)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @mrkn, thank you for your review 🙏
I used assert_in_delta
for your suggestion because the definition of tan
(sin / cos
) makes the two methods' precision sum:
require "bigdecimal/math"
BigMath.sin(BigDecimal("1"), 10)
# => 0.84147098480789650665250231788602089836677454e0
BigMath.cos(BigDecimal("1"), 10)
# => 0.540302305868139717400936607637646275593203e0
BigMath.sin(BigDecimal("1"), 10) / BigMath.cos(BigDecimal("1"), 10)
# => 0.1557407724654902230506974799967261008769125258846034219578498192680719427656331763435628519e1
Using assert_equal
in this case fails as the result has a lot more precision than N
.
Do you think we should change the tan
definition to handle precision differently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we should change the tan definition to handle precision differently?
We must produce at least N
precise digits for BigMath.tan(x, N)
, so the answer is yes.
Instead, I think we can use assert_in_delta
with specifying BigDecimal("1e-#{N+1}")
in the delta
argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @mrkn
Thank you again for reviewing this PR.
I had a look a other tests on the gem and I found that we use assert_in_delta
in most of them, including cos
and sin
.
I understand that this may not be exactly what we're supposed to use for more accurate testing. Although, do you think we should first add this missing method (I'm also planning on adding acos
and asin
right after) the way the rest of the gem was implemented?
I'll be happy to help in the same time on updating gem to assert_in_delta
in a way that is suitable for BigDecimal.
Please let me know what you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason why I'm sticking to a precise alternative of assert_in_delta
is that your implementation of tan
depends on sin
and cos
, and they are tested by assert_in_delta
.
If tan
and other new methods you plan won't depend on other methods tested by assert_in_delta
, it can be merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this explanation and the link to the work on test-unit
, I see better why it is important to wait for a prior work.
I think it's better to stick to a definition of tan
based on sin
and cos
for the simplicity of the gem (of course I'm all ears to counter arguments).
How can I help on your current PR on test-unit
? This is a bit blurry to me but I guess I have to start somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixing assert_in_delta
is almost done. After the new version of test-unit
is released, I will update the master branch of this repository. And then, please rebase this branch and fix the test.
I think it's better to stick to a definition of
tan
based onsin
andcos
for the simplicity of the gem (of course I'm all ears to counter arguments).
If you can implement tan
as a series that converges faster than sin
and cos
, using the series is better. If not, you can at least depend on only sin
by applying basic trigonometric formula
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, we can treat the case of sin
call only in the case of tan
is periodic.
I'm working on supporting BigDecimal in |
I'm working on adding tests with higher precision at #238 |
@rhannequin Although test-unit now supports BigDecimal in Until finishing this work, could you try to rewrite |
Hello @mrkn, I hope you're doing great. I did some research for a new algorithm for I committed it a few minutes ago, what do you think? |
end | ||
|
||
sine / cosine | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rhannequin Could you please mention the origin such as the paper reference of this algorithm in the comment?
And, I want to know how this algorithm is better than just doing sine/(1 - sine**2)
. Could you explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mrkn I don't believe tanθ is defined as sinθ / (1 - sin2θ), but should be sinθ / cosθ and cosθ is √(1 - sin2θ).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nobu The current code was updated against my comment above. Please compare the commit timestamp and the comment timestamp.
aa1e42a
to
38bd414
Compare
@mrkn Hello, sorry for taking so long to move forward with this pull request. My math background is not really advanced and I wasn't familiar with this definition of cosine based on sine. Would you still like a link to a paper or an "official" definition for the documentation? |
@hsbt I allow myself to ping you here as you seem to have been active on the project recently. |
@rhannequin He’s recent work is only for leaving this library out of Ruby’s default gems. I think there are few people who can review new features of bigdecimal in the Ruby core team. Could you please wait until I can look into your new commits? |
Absolutely, @mrkn. Sorry if my comment sounded pressing, I wasn't sure you had time for this at the moment. I'll wait now all the time needed. |
@rhannequin Thank you for your understanding and cooperation! |
Since bigdecimal is now a bundled gem, I think we only need to update the version of test-unit to ensure that the tests can verify the full digits. |
38bd414
to
46dca76
Compare
Associated issue: #81
Context
BigMath
module supports sine (sin
) and cosine (cos
) trigonometric functions. It also supports arctangent (acan
). But it doesn't support tangent, which is supported inMath
module.Solution
tan
is related tosin
andcos
function such as (source):This PR adds
BigMath.tan(x, precision)
, dependent on existingBigMath.sin
andBigMath.cos
methods.