Ruby Wrappers for Real MPFR and Complex MPC #49

Merged
merged 15 commits into from Jun 12, 2016

Projects

None yet

3 participants

@rajithv
Contributor
rajithv commented Jun 1, 2016

No description provided.

rajithv added some commits Jun 1, 2016
@rajithv rajithv Class structure for MPC and MPFR f46d572
@rajithv rajithv realmpfr.c and realmpfr.h
3b490e3
@rajithv
Contributor
rajithv commented Jun 1, 2016

For convert (sympify) I need to check the type of the VALUE objects. When a BigDecimal comes through, what I could come up with so far is to identify it like this:

case T_OBJECT:
VALUE a = rb_funcall(operand2, rb_intern("class"), 0, NULL);
VALUE b = rb_funcall(a, rb_intern("to_s"), 0, NULL);
char *c = RSTRING( VALUE )->ptr

I am pretty sure there should be a better way in doing this. Any help would be great.

@abinashmeher999
Contributor

@rajithv You can use rb_obj_classname. It returns the name of the class as a string. But if you want to obtain the class as a VALUE, you can use the CLASS_OF macro on a VALUE that is an instance of the class.

The first one seems the easier one for now, because if you decide to use CLASS_OF, you need to have a VALUE for BigDecimal that you can compare with what you got.

VALUE bdval = rb_eval_string("BigDecimal.new('0.0001')");
char * c = rb_obj_classname(bdval) ; // this allows to have the class name as "const char *" 
VALUE rb_cBigDecimal = CLASS_OF(bdval) ; // this for a VALUE to the class.

I don't think you will be able to include bigdecimal.h, but that would have made things easier. that way you can use rb_cBigDecimal straightaway.

@rajithv rajithv RealMPFR initiation with doubles - error
c2cac3c
@rajithv rajithv and 1 other commented on an outdated diff Jun 2, 2016
ext/symengine/ruby_real_mpfr.c
+ VALUE result;
+ double d;
+ int prec = NUM2INT(prec_value);
+ cresult = basic_new_heap();
+
+ switch( TYPE(num_value) ) {
+ case T_FLOAT:
+ d = RFLOAT_VALUE(num_value);
+ real_mpfr_set_d(cresult, d, prec);
+ break;
+ default:
+ rb_raise(rb_eTypeError, "Invalid Type: Float, BigDecimal or String required.");
+ break;
+ }
+ result = Data_Wrap_Struct(c_real_mpfr, NULL, cbasic_free_heap, cresult);
+ return result;
@rajithv
rajithv Jun 2, 2016 Contributor

I'm getting a terminate called after throwing an instance of 'Teuchos::NullReferenceError' error right after the return of this code. I've been trying to find out with no luck.

The real_mpfr_set_d function is working, it's being tested in here

Also, I used print statements to make sure that the code runs up until the return statement.

The error is given when I give a sample input like this:

A = SymEngine::RealMPFR.new(10.4, 10)

@abinashmeher999 @isuruf

@isuruf
isuruf Jun 3, 2016 Member

You are trying to return a new ruby VALUE instead of self. See Symbol::initialize

@rajithv
rajithv Jun 3, 2016 Contributor

Thanks @isuruf got it to be working, only to proceed into another confusion.

I'm getting the following output. Should I be worried?

2.1.8 :012 > X = SymEngine::RealMPFR.new(123.456, 200)
 => #<SymEngine::RealMPFR(123.45600000000000306954461848363280296325683593750000000000000)> 
2.1.8 :013 > Y = SymEngine::RealMPFR.new(456.123, 200)
 => #<SymEngine::RealMPFR(456.12299999999999045030563138425350189208984375000000000000000)> 

I am guessing this is to be expected with the arbitrary precision. But just wanted to confirm.

@isuruf
isuruf Jun 3, 2016 Member

That's expected when using floats. Let me know when you have added String input and BigDecimal input.

@rajithv
rajithv Jun 3, 2016 Contributor

String and BigDecimal input added. @isuruf

rajithv added some commits Jun 3, 2016
@rajithv rajithv Float, String constructors for RealMPFR working 9cdab35
@rajithv rajithv BigDecimal to RealMPFR
90cbfec
@rajithv rajithv to_f for RealMPFR
1f8cb65
@rajithv rajithv Spec for RealMPFR
fa54c24
@isuruf isuruf commented on an outdated diff Jun 4, 2016
ext/symengine/symengine_utils.c
@@ -6,7 +6,9 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) {
basic_struct *temp;
VALUE new_operand2, num, den;
VALUE real, imag;
+ VALUE a, b;
@isuruf
isuruf Jun 4, 2016 Member

Can you reuse a, b for num, den and real, imag?

@isuruf isuruf commented on an outdated diff Jun 4, 2016
ext/symengine/symengine_utils.c
@@ -59,10 +61,16 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) {
break;
case T_DATA:
+ c = rb_obj_classname(operand2);
+ if(strcmp(c, "BigDecimal") == 0){
@isuruf
isuruf Jun 4, 2016 Member

See this comment, #49 (comment)
It's much better than comparing strings.

@isuruf
Member
isuruf commented Jun 8, 2016

Can you update the symengine hash to the latest master?

rajithv added some commits Jun 8, 2016
@rajithv rajithv Merge branch 'master' into mpfr_mpc 46c4b0c
@rajithv rajithv Updating SymEngine Version 32eb6ed
@rajithv rajithv to_f working, optimizing TODO
75c0dcc
@isuruf isuruf and 1 other commented on an outdated diff Jun 8, 2016
ext/symengine/symengine_utils.c
@@ -59,10 +61,16 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) {
break;
case T_DATA:
+ c = rb_obj_classname(operand2);
+ if(strcmp(c, "BigDecimal") == 0){
+ c = RSTRING_PTR( rb_funcall(operand2, rb_intern("to_s"), 1, rb_str_new2("F")) );
+ real_mpfr_set_str(cbasic_operand2, c, 200);
@isuruf
isuruf Jun 8, 2016 Member

SymEngine might not have been compiled with MPFR. So you cannot expect real_mpfr_set_str to be available all the time.

@rajithv
rajithv Jun 10, 2016 Contributor

I tried having #ifdef HAVE_SYMENGINE_MPFR , but it does not reach the code even though the symengine was built with MPFR and MPC. How can I find whether symengine has been build with MPFR and/or MPC.

Also, how can I translate that into ruby, because I would need to have a way to check that in the spec as well.

Can we have a function in the cwrapper, which returns true or false, depending on the flag? Then have a Ruby Wrapper for that, to access it from Ruby?

This is the solution I am currently thinking of. What do you think?

@isuruf @abinashmeher999

rajithv added some commits Jun 10, 2016
@rajithv rajithv Reduced no of VALUE variables used 5ca9523
@rajithv rajithv Changed T_DATA Class comparison
3b8d53b
@isuruf isuruf commented on an outdated diff Jun 10, 2016
ext/symengine/ruby_real_mpfr.c
+ int prec = NUM2INT(prec_value);
+
+ Data_Get_Struct(self, basic_struct, cresult);
+
+ switch( TYPE(num_value) ) {
+ case T_FLOAT:
+ d = RFLOAT_VALUE(num_value);
+ real_mpfr_set_d(cresult, d, prec);
+ break;
+ case T_STRING:
+ c = RSTRING_PTR(num_value);
+ real_mpfr_set_str(cresult, c, prec);
+ break;
+ case T_DATA:
+ c = rb_obj_classname(num_value);
+ if(strcmp(c, "BigDecimal") == 0){
@isuruf
isuruf Jun 10, 2016 Member

Space after if and before {

@isuruf isuruf commented on an outdated diff Jun 10, 2016
ext/symengine/ruby_real_mpfr.c
+
+ Data_Get_Struct(self, basic_struct, cresult);
+
+ switch( TYPE(num_value) ) {
+ case T_FLOAT:
+ d = RFLOAT_VALUE(num_value);
+ real_mpfr_set_d(cresult, d, prec);
+ break;
+ case T_STRING:
+ c = RSTRING_PTR(num_value);
+ real_mpfr_set_str(cresult, c, prec);
+ break;
+ case T_DATA:
+ c = rb_obj_classname(num_value);
+ if(strcmp(c, "BigDecimal") == 0){
+ c = RSTRING_PTR( rb_funcall(num_value, rb_intern("to_s"), 1, rb_str_new2("F")) );
@isuruf
isuruf Jun 10, 2016 Member

Remove space after RSTRING_PTR( and before last )

@isuruf isuruf commented on an outdated diff Jun 11, 2016
ext/symengine/symengine_utils.c
double f;
+ char *c;
+ VALUE rb_cBigDecimal;
@isuruf
isuruf Jun 11, 2016 Member

Make this a static variable and initialize the value here.

rajithv added some commits Jun 11, 2016
@rajithv rajithv Updated SymEngine version f092e0d
@rajithv rajithv Adding HAVE_MPFR/MPC as constants, adding HAVE_SYMENGINE_MPFR/MPC che…
…cks, and fixing formating
8e536cf
@isuruf isuruf merged commit 2aab1ec into symengine:master Jun 12, 2016

2 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@isuruf isuruf commented on the diff Jun 13, 2016
ext/symengine/symengine_utils.c
double f;
+ char *c;
+ rb_cBigDecimal = CLASS_OF(rb_eval_string("BigDecimal.new('0.0001')"));
@isuruf
isuruf Jun 13, 2016 Member

This doesn't work for me. Can you revert this back to checking class by name?

@rajithv
Contributor
rajithv commented Jun 13, 2016

@isuruf is it okay if I do it in #51 ?

@rajithv rajithv changed the title from [WIP] Ruby Wrappers for Real MPFR and Complex MPC to Ruby Wrappers for Real MPFR and Complex MPC Jun 13, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment