evalf ruby wrapper #55

Merged
merged 12 commits into from Jul 8, 2016

Projects

None yet

5 participants

@rajithv
Contributor
rajithv commented Jun 17, 2016

No description provided.

rajithv added some commits Jun 17, 2016
@rajithv rajithv evals ruby wrapper
b6a2b45
@rajithv rajithv evalf specs for Ruby Wrapper
2f716e1
@rajithv rajithv changed the title from [WIP] evalf ruby wrapper to evalf ruby wrapper Jun 19, 2016
rajithv added some commits Jun 22, 2016
@rajithv rajithv Changed symengine version
81a0d7a
@rajithv rajithv Fixes #57 a8e3dde
@rajithv rajithv Merge branch 'evals' of https://github.com/rajithv/symengine.rb into …
…evals
7613e7c
@abinashmeher999 abinashmeher999 and 1 other commented on an outdated diff Jun 22, 2016
ext/symengine/ruby_utils.c
@@ -14,3 +14,21 @@ VALUE cutils_sympify(VALUE self, VALUE operand)
return result;
}
+
+VALUE cutils_evalf(VALUE self, VALUE operand, VALUE prec, VALUE real)
+{
+ VALUE result;
+
+ basic_struct *cbasic_operand;
+ basic_struct *cresult;
+ cbasic_operand = basic_new_heap();
@abinashmeher999
abinashmeher999 Jun 22, 2016 Contributor

This can be allocated on the stack.

@isuruf
isuruf Jun 23, 2016 Member

Actually, you can remove this variable completely

@abinashmeher999 abinashmeher999 commented on an outdated diff Jun 22, 2016
spec/evalf_spec.rb
@@ -0,0 +1,29 @@
+describe 'SymEngine::evalf' do
+ context 'RealDouble values' do
+ subject { SymEngine::evalf(SymEngine::sin(SymEngine(2)), 53, true) }
+ it { is_expected.to be_a SymEngine::RealDouble }
+ its(:to_s) { is_expected.to eq "0.909297426825682" }
@abinashmeher999
abinashmeher999 Jun 22, 2016 Contributor

Why not compare directly with 0.909297426825682?

@abinashmeher999 abinashmeher999 and 3 others commented on an outdated diff Jun 22, 2016
spec/evalf_spec.rb
+ its(:to_s) { is_expected.to eq "1.4973429143989597928099399837265e-10" }
+ end
+ end
+ context 'ComplexDouble values' do
+ subject { SymEngine::evalf(SymEngine::sin(1) * SymEngine::I, 53, false) }
+ it { is_expected.to be_a SymEngine::ComplexDouble }
+ its(:to_s) { is_expected.to eq "0.0 + 0.841470984807897*I" }
+ end
+ context 'ComplexMPC values' do
+
+ end
+ if SymEngine::HAVE_MPC
+ context 'ComplexMPC values' do
+ subject { SymEngine::evalf(SymEngine::sin(1) * SymEngine::I, 100, false) }
+ it { is_expected.to be_a SymEngine::ComplexMPC }
+ its(:to_s) { is_expected.to eq "0.00000000000000000000000000000000 + 0.84147098480789650665250232163005*I" }
@abinashmeher999
abinashmeher999 Jun 22, 2016 Contributor

Same for line 11 and 26

@rajithv
rajithv Jun 22, 2016 Contributor

@abinashmeher999 5 and 17 can be done. But for 11 and 26, directly comparing would be at a loss of precision, right?

@rajithv
rajithv Jun 22, 2016 edited Contributor

@abinashmeher999 even 5 and 17 are not possible unless I compare directly with SymEngine::RealDouble(0.909297426825682). This works in the irb, but fails the rspec. Even though they compare using the ==.

@abinashmeher999
abinashmeher999 Jun 23, 2016 Contributor

So to not lose precision we should use BigDecimal and then compare. In 5 and 17, if the numbers are BigDecimals, can they be compared then? Like

# 5
BigDecimal("0.909297426825682")
# 17 
Complex(0.0, BigDecimal("0.841470984807897"))

There will be a little problem in line 26 but 11 can be done with BigDecimal.
In 26, BigDecimal("0.00000000000000000000000000000000") reduces the precision to 0.0. I couldn't find a way to retain it as it is.

@isuruf
isuruf Jun 23, 2016 Member

You should not directly compare floats in tests.
For example, you should do abs(a-b) < tol for floating points.

For this you need to define the operator < for SymEngine::Number

@zverok
zverok Jun 23, 2016 Collaborator

rspec's default functionality for comparing floats is be_within matcher.

@isuruf
isuruf Jun 23, 2016 Member

@zverok, be_within does exactly that. We just need to define .abs object method and the <= operator

@rajithv rajithv Update ruby_utils.h - removed cbasic_operand
bb29a1b
@v0dro
v0dro commented Jul 5, 2016

@rajithv Any reason why this has not been merged yet?

@v0dro
v0dro commented Jul 5, 2016

@rajithv Any reason why this has not been merged yet?

@isuruf isuruf commented on an outdated diff Jul 6, 2016
ext/symengine/symengine.c
@@ -57,6 +57,9 @@ void Init_symengine()
// Sympify as a Module Level Function
rb_define_module_function(m_symengine, "convert", cutils_sympify, 1);
rb_define_global_function("SymEngine", cutils_sympify, 1);
+
+ // evalf as a Module Level Function
+ rb_define_module_function(m_symengine, "evalf", cutils_evalf, 3);
@isuruf
isuruf Jul 6, 2016 Member

Currently you need to give all 3 parameters. Can you change it so that only 1 parameter is required and the other 2 have default values 53 and False

@isuruf
isuruf Jul 6, 2016 Member

Maybe it's easier if you did it in pure ruby and you rename this method to something like _evalf which can be called from evalf pure ruby method.

rajithv added some commits Jul 7, 2016
@rajithv rajithv Default values for evalf, .abs object method d38b5c8
@rajithv rajithv comparisons for Number class 00d5633
@rajithv rajithv Changed spec and fixes for comparisons c7ef759
@rajithv rajithv Merge branch 'evals' of https://github.com/rajithv/symengine.rb into …
…evals
cc88799
@isuruf isuruf commented on the diff Jul 8, 2016
ext/symengine/ruby_number.c
@@ -0,0 +1,45 @@
+#include "ruby_number.h"
+
+int cnumber_comp(VALUE self, VALUE operand2)
+{
+ basic cbasic_operand1;
+ basic cbasic_operand2;
+ basic_new_stack(cbasic_operand1);
+ basic_new_stack(cbasic_operand2);
+
+ basic cbasic_sub;
+ basic_new_stack(cbasic_sub);
+
+ sympify(self, cbasic_operand1);
+ sympify(operand2, cbasic_operand2);
+
@isuruf
isuruf Jul 8, 2016 Member

You have to check here that cbasic_operand2 is also a Number

@isuruf isuruf commented on an outdated diff Jul 8, 2016
spec/evalf_spec.rb
@@ -2,28 +2,26 @@
context 'RealDouble values' do
subject { SymEngine::evalf(SymEngine::sin(SymEngine(2)), 53, true) }
it { is_expected.to be_a SymEngine::RealDouble }
- its(:to_s) { is_expected.to eq "0.909297426825682" }
+ it { is_expected.to be_within(0.000000000000001).of(0.909297426825682) }
@isuruf
isuruf Jul 8, 2016 Member

0.000000000000001 -> 1e-15

@isuruf isuruf commented on an outdated diff Jul 8, 2016
spec/evalf_spec.rb
+ subject { SymEngine::evalf(SymEngine::PI * SymEngine(1963319607) - SymEngine(6167950454), 100, true) }
+ it { is_expected.to be_a SymEngine::RealMPFR }
+ it { is_expected.to be_within(SymEngine::RealMPFR.new(0.0000000000000000000000000000001e-10, 100)).of(SymEngine::RealMPFR.new(1.4973429143989597928099399837265e-10, 100)) }
+ end
+ end
+ context 'ComplexDouble values' do
+ subject { SymEngine::evalf(SymEngine::sin(1) * SymEngine::I, 53, false) }
+ it { is_expected.to be_a SymEngine::ComplexDouble }
+ its(:imaginary) { is_expected.to be_within(0.000000000000001).of(0.841470984807897) }
+ end
+
+ if SymEngine::HAVE_MPC
+ context 'ComplexMPC values' do
+ subject { SymEngine::evalf(SymEngine::sin(1) * SymEngine::I, 100, false) }
+ it { is_expected.to be_a SymEngine::ComplexMPC }
+ its(:imaginary) { is_expected.to be_within(SymEngine::RealMPFR.new(0.00000000000000000000000000000001, 100)).of(SymEngine::RealMPFR.new(0.84147098480789650665250232163005, 100)) }
@isuruf
isuruf Jul 8, 2016 Member

Use strings, SymEngine::RealMPFR.new("1e-32", 100)

@isuruf
isuruf Jul 8, 2016 Member

SymEngine::RealMPFR.new("0.84147098480789650665250232163005", 100)

rajithv added some commits Jul 8, 2016
@rajithv rajithv ComplexMPC imaginary and real methods, evalf tests
01d3743
@rajithv rajithv Updated symengine version
9e2be3f
@isuruf
Member
isuruf commented Jul 8, 2016

+1 to merge if tests pass

@isuruf isuruf merged commit c9dce78 into symengine:master Jul 8, 2016

2 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@isuruf
Member
isuruf commented Jul 8, 2016

Thanks for the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment