-
Notifications
You must be signed in to change notification settings - Fork 15
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
Ruby Wrappers for Real MPFR and Complex MPC #49
Changes from 7 commits
f46d572
3b490e3
c2cac3c
9cdab35
90cbfec
1f8cb65
fa54c24
166dd25
46c4b0c
32eb6ed
75c0dcc
5ca9523
3b8d53b
f092e0d
8e536cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include "ruby_real_mpfr.h" | ||
|
||
VALUE crealmpfr_init(VALUE self, VALUE num_value, VALUE prec_value) | ||
{ | ||
basic_struct *cresult; | ||
double d; | ||
char *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){ | ||
c = RSTRING_PTR( rb_funcall(num_value, rb_intern("to_s"), 1, rb_str_new2("F")) ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove space after |
||
real_mpfr_set_str(cresult, c, prec); | ||
break; | ||
} | ||
default: | ||
rb_raise(rb_eTypeError, "Invalid Type: Float, BigDecimal or String required."); | ||
break; | ||
} | ||
|
||
return self; | ||
} | ||
|
||
VALUE crealmpfr_to_float(VALUE self) | ||
{ | ||
VALUE result; | ||
basic cbasic_operand1; | ||
basic_new_stack(cbasic_operand1); | ||
sympify(self, cbasic_operand1); | ||
|
||
result = rb_float_new(real_mpfr_get_d(cbasic_operand1)); | ||
|
||
basic_free_stack(cbasic_operand1); | ||
return result; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm getting a 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:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are trying to return a new ruby VALUE instead of self. See There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @isuruf got it to be working, only to proceed into another confusion. I'm getting the following output. Should I be worried?
I am guessing this is to be expected with the arbitrary precision. But just wanted to confirm. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's expected when using floats. Let me know when you have added String input and BigDecimal input. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. String and BigDecimal input added. @isuruf |
||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#ifndef RUBY_REAL_MPFR_H_ | ||
#define RUBY_REAL_MPFR_H_ | ||
|
||
#include <ruby.h> | ||
#include <symengine/cwrapper.h> | ||
|
||
#include "symengine.h" | ||
#include "symengine_utils.h" | ||
|
||
VALUE crealmpfr_init(VALUE self, VALUE num_value, VALUE prec_value); | ||
VALUE crealmpfr_to_float(VALUE self); | ||
|
||
#endif //RUBY_REAL_MPFR_H_ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you reuse |
||
double f; | ||
char *c; | ||
|
||
switch(TYPE(operand2)) { | ||
case T_FIXNUM: | ||
|
@@ -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){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See this comment, #49 (comment) |
||
c = RSTRING_PTR( rb_funcall(operand2, rb_intern("to_s"), 1, rb_str_new2("F")) ); | ||
real_mpfr_set_str(cbasic_operand2, c, 200); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SymEngine might not have been compiled with MPFR. So you cannot expect There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried having 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? |
||
break; | ||
} | ||
|
||
Data_Get_Struct(operand2, basic_struct, temp); | ||
basic_assign(cbasic_operand2, temp); | ||
break; | ||
|
||
} | ||
} | ||
|
||
|
@@ -87,12 +95,16 @@ VALUE Klass_of_Basic(const basic_struct *basic_ptr) { | |
return c_integer; | ||
case SYMENGINE_REAL_DOUBLE: | ||
return c_real_double; | ||
case SYMENGINE_REAL_MPFR: | ||
return c_real_mpfr; | ||
case SYMENGINE_RATIONAL: | ||
return c_rational; | ||
case SYMENGINE_COMPLEX: | ||
return c_complex; | ||
case SYMENGINE_COMPLEX_DOUBLE: | ||
return c_complex_double; | ||
case SYMENGINE_COMPLEX_MPC: | ||
return c_complex_mpc; | ||
case SYMENGINE_CONSTANT: | ||
return c_constant; | ||
case SYMENGINE_ADD: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
require 'bigdecimal' | ||
|
||
describe SymEngine::RealMPFR do | ||
describe 'Convert BigDemcimal to RealMPFR' do | ||
shared_examples 'simple real check' do | ||
subject { SymEngine(value) } | ||
|
||
it { is_expected.to be_a SymEngine::RealMPFR } | ||
its(:to_f) { is_expected.to eq value.to_f } | ||
end | ||
|
||
context 'positive BigDecimal' do | ||
let(:value) { BigDecimal("12.3") } | ||
|
||
it_behaves_like 'simple real check' | ||
end | ||
|
||
context 'negative BigDecimal' do | ||
let(:value) { BigDecimal("-12.3") } | ||
|
||
it_behaves_like 'simple real check' | ||
end | ||
end | ||
|
||
describe 'Initialize RealMPFR' do | ||
shared_examples 'simple real check' do | ||
subject { SymEngine::RealMPFR.new(value, 200) } | ||
|
||
it { is_expected.to be_a SymEngine::RealMPFR } | ||
its(:to_f) { is_expected.to eq value.to_f } | ||
end | ||
|
||
context 'positive BigDecimal' do | ||
let(:value) { BigDecimal("12.3") } | ||
|
||
it_behaves_like 'simple real check' | ||
end | ||
|
||
context 'negative BigDecimal' do | ||
let(:value) { BigDecimal("-12.3") } | ||
|
||
it_behaves_like 'simple real check' | ||
end | ||
|
||
context 'positive Float' do | ||
let(:value) { 12.3 } | ||
|
||
it_behaves_like 'simple real check' | ||
end | ||
|
||
context 'negative Float' do | ||
let(:value) { 12.3 } | ||
|
||
it_behaves_like 'simple real check' | ||
end | ||
|
||
context 'String representation of positive value' do | ||
let(:value) { "12.3" } | ||
|
||
it_behaves_like 'simple real check' | ||
end | ||
|
||
context 'String representation of negative value' do | ||
let(:value) { "-12.3" } | ||
|
||
it_behaves_like 'simple real check' | ||
end | ||
end | ||
|
||
|
||
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.
Space after
if
and before{