From f9b06616cd4317302e794fe05c5e24c2c878054d Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Mon, 23 May 2016 19:20:42 +0530 Subject: [PATCH 01/26] Basic structure for complex --- ext/symengine/CMakeLists.txt | 1 + ext/symengine/ruby_complex.c | 23 +++++++++++++++++++++++ ext/symengine/ruby_complex.h | 8 ++++++++ ext/symengine/symengine.c | 6 ++++++ ext/symengine/symengine.h | 1 + 5 files changed, 39 insertions(+) create mode 100644 ext/symengine/ruby_complex.c create mode 100644 ext/symengine/ruby_complex.h diff --git a/ext/symengine/CMakeLists.txt b/ext/symengine/CMakeLists.txt index b587bb6..879f3d5 100644 --- a/ext/symengine/CMakeLists.txt +++ b/ext/symengine/CMakeLists.txt @@ -3,6 +3,7 @@ set(RUBY_WRAPPER_SRC ruby_symbol.c ruby_integer.c ruby_rational.c + ruby_complex.c ruby_constant.c ruby_function.c ruby_ntheory.c diff --git a/ext/symengine/ruby_complex.c b/ext/symengine/ruby_complex.c new file mode 100644 index 0000000..f5d85cf --- /dev/null +++ b/ext/symengine/ruby_complex.c @@ -0,0 +1,23 @@ +#include "ruby_complex.h" + +VALUE ccomplex_init(VALUE self, VALUE comp_value) { + basic_struct *this; + basic real_basic, imag_basic; + + basic_new_stack(real_basic); + basic_new_stack(imag_basic); + + Data_Get_Struct(self, basic_struct, this); + + VALUE real, imag; + real = rb_funcall(comp_value, rb_intern("real"), 0, NULL); + imag = rb_funcall(comp_value, rb_intern("imaginary"), 0, NULL); + + crational_init(real_basic, real); + crational_init(imag_basic, imag); + + complex_set(this, real_basic, imag_basic); + basic_free_stack(real_basic); + basic_free_stack(imag_basic); + return self; +} diff --git a/ext/symengine/ruby_complex.h b/ext/symengine/ruby_complex.h new file mode 100644 index 0000000..c8a3bbb --- /dev/null +++ b/ext/symengine/ruby_complex.h @@ -0,0 +1,8 @@ +#ifndef RUBY_COMPLEX_H_ +#define RUBY_COMPLEX_H_ + +#include "ruby_basic.h" + +VALUE ccomplex_init(VALUE self, VALUE comp_value); + +#endif //RUBY_COMPLEX_H_ diff --git a/ext/symengine/symengine.c b/ext/symengine/symengine.c index 2f9f22c..ae8cacf 100644 --- a/ext/symengine/symengine.c +++ b/ext/symengine/symengine.c @@ -3,6 +3,7 @@ #include "ruby_symbol.h" #include "ruby_integer.h" #include "ruby_rational.h" +#include "ruby_complex.h" #include "ruby_constant.h" #include "ruby_function.h" #include "ruby_ntheory.h" @@ -60,6 +61,11 @@ void Init_symengine() { rb_define_alloc_func(c_rational, cbasic_alloc); rb_define_method(c_rational, "initialize", crational_init, 1); + //Complex class + c_complex = rb_define_class_under(m_symengine, "Complex", c_basic); + rb_define_alloc_func(c_complex, cbasic_alloc); + rb_define_method(c_complex, "initialize", ccomplex_init, 1); + //Constant class c_constant = rb_define_class_under(m_symengine, "Constant", c_basic); diff --git a/ext/symengine/symengine.h b/ext/symengine/symengine.h index 5893a2c..2fed187 100644 --- a/ext/symengine/symengine.h +++ b/ext/symengine/symengine.h @@ -11,6 +11,7 @@ VALUE c_basic; VALUE c_symbol; VALUE c_integer; VALUE c_rational; +VALUE c_complex; VALUE c_constant; VALUE c_add; VALUE c_mul; From b4af3b029b9058a1074d5dcbed66a3444949a322 Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Mon, 23 May 2016 23:47:19 +0530 Subject: [PATCH 02/26] Rational spec changed to reflect required changes --- spec/rational_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/rational_spec.rb b/spec/rational_spec.rb index c32b0dc..506d620 100644 --- a/spec/rational_spec.rb +++ b/spec/rational_spec.rb @@ -11,6 +11,12 @@ expect(a.to_s).to eq('2/3') end end + context 'with a Ruby Integer as input' do + it 'returns an instance of SymEngine::Integer class' do + a = SymEngine::Rational.new(2/1) + expect(a).to be_a SymEngine::Integer + end + end end describe 'coercion tests' do From 316a9c1fcada3d89b0f11f900c3aa7fe3844049f Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Mon, 23 May 2016 23:49:02 +0530 Subject: [PATCH 03/26] Adding spec for Complex --- spec/complex_spec.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 spec/complex_spec.rb diff --git a/spec/complex_spec.rb b/spec/complex_spec.rb new file mode 100644 index 0000000..71bceee --- /dev/null +++ b/spec/complex_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe SymEngine do + describe SymEngine::Complex do + describe '.new' do + context 'with a Ruby Complex object as input' do + it 'returns an instance of SymEngine::Complex class' do + a = Complex(2, 3) + a = SymEngine::Complex.new(a) + expect(a).to be_a SymEngine::Complex + expect(a.to_s).to eq('2+3i') + end + end + context 'with a Ruby Integer as input' do + it 'returns an instance of SymEngine::Integer class' do + a = SymEngine::Complex.new(2) + expect(a).to be_a SymEngine::Integer + end + end + end + end +end From 88b302fa962094e32432a6bb72ca9cbff57bbbf1 Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Tue, 24 May 2016 22:30:35 +0530 Subject: [PATCH 04/26] Exposed sympify to Ruby --- ext/symengine/CMakeLists.txt | 1 + ext/symengine/ruby_complex.c | 12 ++++++------ ext/symengine/ruby_utils.c | 15 +++++++++++++++ ext/symengine/ruby_utils.h | 9 +++++++++ ext/symengine/symengine.c | 5 +++++ ext/symengine/symengine_utils.c | 1 + 6 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 ext/symengine/ruby_utils.c create mode 100644 ext/symengine/ruby_utils.h diff --git a/ext/symengine/CMakeLists.txt b/ext/symengine/CMakeLists.txt index 879f3d5..6fec152 100644 --- a/ext/symengine/CMakeLists.txt +++ b/ext/symengine/CMakeLists.txt @@ -7,6 +7,7 @@ set(RUBY_WRAPPER_SRC ruby_constant.c ruby_function.c ruby_ntheory.c + ruby_utils.c symengine_utils.c symengine.c ) diff --git a/ext/symengine/ruby_complex.c b/ext/symengine/ruby_complex.c index f5d85cf..4dc9799 100644 --- a/ext/symengine/ruby_complex.c +++ b/ext/symengine/ruby_complex.c @@ -2,10 +2,8 @@ VALUE ccomplex_init(VALUE self, VALUE comp_value) { basic_struct *this; - basic real_basic, imag_basic; - - basic_new_stack(real_basic); - basic_new_stack(imag_basic); + basic_struct *real_basic = basic_new_heap(); + basic_struct *imag_basic = basic_new_heap(); Data_Get_Struct(self, basic_struct, this); @@ -17,7 +15,9 @@ VALUE ccomplex_init(VALUE self, VALUE comp_value) { crational_init(imag_basic, imag); complex_set(this, real_basic, imag_basic); - basic_free_stack(real_basic); - basic_free_stack(imag_basic); + + basic_free_heap(real_basic); + basic_free_heap(imag_basic); + return self; } diff --git a/ext/symengine/ruby_utils.c b/ext/symengine/ruby_utils.c new file mode 100644 index 0000000..a25dd47 --- /dev/null +++ b/ext/symengine/ruby_utils.c @@ -0,0 +1,15 @@ +#include "ruby_utils.h" + +VALUE cutils_sympify(VALUE self, VALUE operand) { + + VALUE result; + basic cbasic_operand; + basic_new_stack(cbasic_operand); + + sympify(operand, cbasic_operand); + result = Data_Wrap_Struct(Klass_of_Basic(cbasic_operand), NULL , cbasic_free_heap, cbasic_operand); + + return operand; + +} + diff --git a/ext/symengine/ruby_utils.h b/ext/symengine/ruby_utils.h new file mode 100644 index 0000000..84df641 --- /dev/null +++ b/ext/symengine/ruby_utils.h @@ -0,0 +1,9 @@ +#ifndef RUBY_UTILS_H_ +#define RUBY_UTILS_H_ + +#include "symengine_utils.h" + +//Returns the Ruby Value after going through sympify +VALUE cutils_sympify(VALUE self, VALUE operand); + +#endif //RUBY_UTILS_H_ diff --git a/ext/symengine/symengine.c b/ext/symengine/symengine.c index ae8cacf..e5899b7 100644 --- a/ext/symengine/symengine.c +++ b/ext/symengine/symengine.c @@ -7,6 +7,8 @@ #include "ruby_constant.h" #include "ruby_function.h" #include "ruby_ntheory.h" +#include "ruby_utils.h" +#include "symengine_utils.h" #include "symengine.h" /////////////////// @@ -45,6 +47,9 @@ void Init_symengine() { rb_define_method(c_basic, "subs", cbasic_subs, -1); rb_define_method(c_basic, "coerce", cbasic_coerce, 1); + //Sympify as a Module Level Function + rb_define_module_function(m_symengine, "sympify", cutils_sympify, 1); + //Symbol class c_symbol = rb_define_class_under(m_symengine, "Symbol", c_basic); rb_define_alloc_func(c_symbol, cbasic_alloc); diff --git a/ext/symengine/symengine_utils.c b/ext/symengine/symengine_utils.c index f914ac3..2bbf17b 100644 --- a/ext/symengine/symengine_utils.c +++ b/ext/symengine/symengine_utils.c @@ -2,6 +2,7 @@ #include "symengine.h" void sympify(VALUE operand2, basic_struct *cbasic_operand2) { + basic_struct *temp; VALUE new_operand2, num, den; From dbd072da3b3453d42f0f147c0d2d4c77ae72072f Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Tue, 24 May 2016 23:04:19 +0530 Subject: [PATCH 05/26] Expose sympify to Ruby - correction --- ext/symengine/ruby_utils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/symengine/ruby_utils.c b/ext/symengine/ruby_utils.c index a25dd47..fd80893 100644 --- a/ext/symengine/ruby_utils.c +++ b/ext/symengine/ruby_utils.c @@ -3,13 +3,13 @@ VALUE cutils_sympify(VALUE self, VALUE operand) { VALUE result; - basic cbasic_operand; - basic_new_stack(cbasic_operand); + + basic_struct *cbasic_operand; + cbasic_operand = basic_new_heap(); sympify(operand, cbasic_operand); result = Data_Wrap_Struct(Klass_of_Basic(cbasic_operand), NULL , cbasic_free_heap, cbasic_operand); - return operand; - + return result; } From d1498f4810d09a49486b3ce132be1b7603ac1ba7 Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Tue, 24 May 2016 23:50:53 +0530 Subject: [PATCH 06/26] Added complex to klass of basic & sympify --- ext/symengine/symengine_utils.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ext/symengine/symengine_utils.c b/ext/symengine/symengine_utils.c index 2bbf17b..6724049 100644 --- a/ext/symengine/symengine_utils.c +++ b/ext/symengine/symengine_utils.c @@ -5,6 +5,7 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) { basic_struct *temp; VALUE new_operand2, num, den; + VALUE real, imag; switch(TYPE(operand2)) { case T_FIXNUM: @@ -29,6 +30,22 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) { basic_free_stack(den_basic); break; + case T_COMPLEX: + real = rb_funcall(operand2, rb_intern("real"), 0, NULL); + imag = rb_funcall(operand2, rb_intern("denominator"), 0, NULL); + + basic_struct *real_basic = basic_new_heap(); + basic_struct *imag_basic = basic_new_heap(); + + sympify(real, real_basic); + sympify(imag, imag_basic); + + complex_set(cbasic_operand2, real_basic, imag_basic); + + basic_free_heap(real_basic); + basic_free_heap(imag_basic); + break; + case T_DATA: Data_Get_Struct(operand2, basic_struct, temp); basic_assign(cbasic_operand2, temp); @@ -44,6 +61,8 @@ VALUE Klass_of_Basic(const basic_struct *basic_ptr) { return c_integer; case SYMENGINE_RATIONAL: return c_rational; + case SYMENGINE_COMPLEX: + return c_complex; case SYMENGINE_CONSTANT: return c_constant; case SYMENGINE_ADD: From 62d67ed3e585a95a369e4a3c63440b40a91d8df3 Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 00:33:23 +0530 Subject: [PATCH 07/26] Removed inits of Complex and Rational. This fixes #19 and fixes #21 --- ext/symengine/CMakeLists.txt | 2 -- ext/symengine/ruby_complex.c | 23 ----------------------- ext/symengine/ruby_complex.h | 8 -------- ext/symengine/ruby_rational.c | 23 ----------------------- ext/symengine/ruby_rational.h | 8 -------- ext/symengine/symengine.c | 4 ---- spec/rational_spec.rb | 14 ++++++++++++-- 7 files changed, 12 insertions(+), 70 deletions(-) delete mode 100644 ext/symengine/ruby_complex.c delete mode 100644 ext/symengine/ruby_complex.h delete mode 100644 ext/symengine/ruby_rational.c delete mode 100644 ext/symengine/ruby_rational.h diff --git a/ext/symengine/CMakeLists.txt b/ext/symengine/CMakeLists.txt index 6fec152..d9efad8 100644 --- a/ext/symengine/CMakeLists.txt +++ b/ext/symengine/CMakeLists.txt @@ -2,8 +2,6 @@ set(RUBY_WRAPPER_SRC ruby_basic.c ruby_symbol.c ruby_integer.c - ruby_rational.c - ruby_complex.c ruby_constant.c ruby_function.c ruby_ntheory.c diff --git a/ext/symengine/ruby_complex.c b/ext/symengine/ruby_complex.c deleted file mode 100644 index 4dc9799..0000000 --- a/ext/symengine/ruby_complex.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "ruby_complex.h" - -VALUE ccomplex_init(VALUE self, VALUE comp_value) { - basic_struct *this; - basic_struct *real_basic = basic_new_heap(); - basic_struct *imag_basic = basic_new_heap(); - - Data_Get_Struct(self, basic_struct, this); - - VALUE real, imag; - real = rb_funcall(comp_value, rb_intern("real"), 0, NULL); - imag = rb_funcall(comp_value, rb_intern("imaginary"), 0, NULL); - - crational_init(real_basic, real); - crational_init(imag_basic, imag); - - complex_set(this, real_basic, imag_basic); - - basic_free_heap(real_basic); - basic_free_heap(imag_basic); - - return self; -} diff --git a/ext/symengine/ruby_complex.h b/ext/symengine/ruby_complex.h deleted file mode 100644 index c8a3bbb..0000000 --- a/ext/symengine/ruby_complex.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef RUBY_COMPLEX_H_ -#define RUBY_COMPLEX_H_ - -#include "ruby_basic.h" - -VALUE ccomplex_init(VALUE self, VALUE comp_value); - -#endif //RUBY_COMPLEX_H_ diff --git a/ext/symengine/ruby_rational.c b/ext/symengine/ruby_rational.c deleted file mode 100644 index 4093789..0000000 --- a/ext/symengine/ruby_rational.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "ruby_rational.h" - -VALUE crational_init(VALUE self, VALUE rat_value) { - basic_struct *this; - basic num_basic, den_basic; - - basic_new_stack(num_basic); - basic_new_stack(den_basic); - - Data_Get_Struct(self, basic_struct, this); - - VALUE num, den; - num = rb_funcall(rat_value, rb_intern("numerator"), 0, NULL); - den = rb_funcall(rat_value, rb_intern("denominator"), 0, NULL); - - GET_SYMINTFROMVAL(num, num_basic); - GET_SYMINTFROMVAL(den, den_basic); - - rational_set(this, num_basic, den_basic); - basic_free_stack(num_basic); - basic_free_stack(den_basic); - return self; -} diff --git a/ext/symengine/ruby_rational.h b/ext/symengine/ruby_rational.h deleted file mode 100644 index 6946f28..0000000 --- a/ext/symengine/ruby_rational.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef RUBY_RATIONAL_H_ -#define RUBY_RATIONAL_H_ - -#include "ruby_basic.h" - -VALUE crational_init(VALUE self, VALUE rat_value); - -#endif //RUBY_RATIONAL_H_ diff --git a/ext/symengine/symengine.c b/ext/symengine/symengine.c index e5899b7..a18f483 100644 --- a/ext/symengine/symengine.c +++ b/ext/symengine/symengine.c @@ -2,8 +2,6 @@ #include "ruby_basic.h" #include "ruby_symbol.h" #include "ruby_integer.h" -#include "ruby_rational.h" -#include "ruby_complex.h" #include "ruby_constant.h" #include "ruby_function.h" #include "ruby_ntheory.h" @@ -64,12 +62,10 @@ void Init_symengine() { //Rational class c_rational = rb_define_class_under(m_symengine, "Rational", c_basic); rb_define_alloc_func(c_rational, cbasic_alloc); - rb_define_method(c_rational, "initialize", crational_init, 1); //Complex class c_complex = rb_define_class_under(m_symengine, "Complex", c_basic); rb_define_alloc_func(c_complex, cbasic_alloc); - rb_define_method(c_complex, "initialize", ccomplex_init, 1); //Constant class c_constant = rb_define_class_under(m_symengine, "Constant", c_basic); diff --git a/spec/rational_spec.rb b/spec/rational_spec.rb index 506d620..adab0a1 100644 --- a/spec/rational_spec.rb +++ b/spec/rational_spec.rb @@ -6,15 +6,25 @@ context 'with a Ruby Rational object as input' do it 'returns an instance of SymEngine::Rational class' do a = Rational('2/3') - a = SymEngine::Rational.new(a) + a = SymEngine::sympify(a) expect(a).to be_a SymEngine::Rational expect(a.to_s).to eq('2/3') end end context 'with a Ruby Integer as input' do it 'returns an instance of SymEngine::Integer class' do - a = SymEngine::Rational.new(2/1) + a = Rational('2/1') + a = SymEngine::sympify(a) expect(a).to be_a SymEngine::Integer + expect(a.to_s).to eq('2') + end + end + context 'with a Ruby Integer (x/x) as input' do + it 'returns an instance of SymEngine::Integer class' do + a = Rational('5/5') + a = SymEngine::sympify(a) + expect(a).to be_a SymEngine::Integer + expect(a.to_s).to eq('1') end end end From 505618ac96f1c30d1e2e862b7bdfedb09daeb19f Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 00:38:26 +0530 Subject: [PATCH 08/26] Rational Spec updated to replace .new with Sympify --- spec/rational_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/rational_spec.rb b/spec/rational_spec.rb index adab0a1..aee3ef9 100644 --- a/spec/rational_spec.rb +++ b/spec/rational_spec.rb @@ -39,13 +39,13 @@ it 'succeeds with commutative operations' do c = @a * @b expect(c).to be_a SymEngine::Basic - expect(c).to eq(SymEngine::Rational.new(@b) * @a) + expect(c).to eq(SymEngine::sympify(@b) * @a) end it 'succeeds with non commutative operations' do c = @a / @b expect(c).to be_a SymEngine::Basic - expect(c).to eq(@a / SymEngine::Rational.new(@b)) + expect(c).to eq(@a / SymEngine::sympify(@b)) end end @@ -53,13 +53,13 @@ it 'succeeds with commutative operations' do c = @b * @a expect(c).to be_a SymEngine::Basic - expect(c).to eq(@a * SymEngine::Rational.new(@b)) + expect(c).to eq(@a * SymEngine::sympify(@b)) end it 'succeeds with non commutative operations' do c = @b / @a expect(c).to be_a SymEngine::Basic - expect(c).to eq(SymEngine::Rational.new(@b) / @a) + expect(c).to eq(SymEngine::sympify(@b) / @a) end end end From dd79ff0fd4ddaf2c9b18250ba80c74e554b72b7c Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 01:03:51 +0530 Subject: [PATCH 09/26] Ruby wrapper for i, the constant --- ext/symengine/ruby_constant.c | 4 ++++ ext/symengine/ruby_constant.h | 2 ++ ext/symengine/symengine.c | 1 + spec/constant_spec.rb | 12 ++++++++++++ 4 files changed, 19 insertions(+) diff --git a/ext/symengine/ruby_constant.c b/ext/symengine/ruby_constant.c index 8e110b6..95bba36 100644 --- a/ext/symengine/ruby_constant.c +++ b/ext/symengine/ruby_constant.c @@ -22,3 +22,7 @@ VALUE cconstant_e() { VALUE cconstant_euler_gamma() { return cconstant_const(basic_const_EulerGamma); } + +VALUE cconstant_i() { + return cconstant_const(basic_const_I); +} diff --git a/ext/symengine/ruby_constant.h b/ext/symengine/ruby_constant.h index bfaeabe..c1032da 100644 --- a/ext/symengine/ruby_constant.h +++ b/ext/symengine/ruby_constant.h @@ -15,4 +15,6 @@ VALUE cconstant_e(); VALUE cconstant_euler_gamma(); +VALUE cconstant_i(); + #endif //RUBY_CONSTANTS_H_ diff --git a/ext/symengine/symengine.c b/ext/symengine/symengine.c index a18f483..909eb99 100644 --- a/ext/symengine/symengine.c +++ b/ext/symengine/symengine.c @@ -74,6 +74,7 @@ void Init_symengine() { rb_define_const(m_symengine, "PI", cconstant_pi()); rb_define_const(m_symengine, "E", cconstant_e()); rb_define_const(m_symengine, "EULER_GAMMA", cconstant_euler_gamma()); + rb_define_const(m_symengine, "I", cconstant_i()); //Add class c_add = rb_define_class_under(m_symengine, "Add", c_basic); diff --git a/spec/constant_spec.rb b/spec/constant_spec.rb index d90dd88..cd48448 100644 --- a/spec/constant_spec.rb +++ b/spec/constant_spec.rb @@ -12,6 +12,7 @@ @d = SymEngine::Integer.new(1); @e = SymEngine::Integer.new(0); @x = SymEngine::Symbol.new("x"); + @i = SymEngine::I end describe '#pi' do @@ -32,6 +33,17 @@ end + describe '#i' do + context 'when squared' do + it 'returns -1' do + f = @i * @i + expect(@i).to be_an_instance_of SymEngine::Constant + expect(f).to be_a SymEngine::Basic + expect(f.to_s).to eql('-1') + end + end + end + describe '#EulerGamma' do context 'with powered to zero' do it 'returns an initialised Basic object that is equalent 1' do From 0f4694a096ff756e6380858f03751000a0dbd916 Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 01:23:07 +0530 Subject: [PATCH 10/26] Complex numbers done --- ext/symengine/symengine_utils.c | 2 +- spec/complex_spec.rb | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/symengine/symengine_utils.c b/ext/symengine/symengine_utils.c index 6724049..0234628 100644 --- a/ext/symengine/symengine_utils.c +++ b/ext/symengine/symengine_utils.c @@ -32,7 +32,7 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) { case T_COMPLEX: real = rb_funcall(operand2, rb_intern("real"), 0, NULL); - imag = rb_funcall(operand2, rb_intern("denominator"), 0, NULL); + imag = rb_funcall(operand2, rb_intern("imaginary"), 0, NULL); basic_struct *real_basic = basic_new_heap(); basic_struct *imag_basic = basic_new_heap(); diff --git a/spec/complex_spec.rb b/spec/complex_spec.rb index 71bceee..b4214bc 100644 --- a/spec/complex_spec.rb +++ b/spec/complex_spec.rb @@ -6,15 +6,17 @@ context 'with a Ruby Complex object as input' do it 'returns an instance of SymEngine::Complex class' do a = Complex(2, 3) - a = SymEngine::Complex.new(a) + a = SymEngine::sympify(a) expect(a).to be_a SymEngine::Complex - expect(a.to_s).to eq('2+3i') + expect(a.to_s).to eq('2 + 3*I') end end context 'with a Ruby Integer as input' do it 'returns an instance of SymEngine::Integer class' do - a = SymEngine::Complex.new(2) + a = 2 + 0i; + a = SymEngine::sympify(a) expect(a).to be_a SymEngine::Integer + expect(a.to_s).to eq('2') end end end From 6633cb40e1d93768f12d866f2a5655515504078a Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 13:32:51 +0530 Subject: [PATCH 11/26] Edited complex to accept not only rational --- ext/symengine/symengine_utils.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ext/symengine/symengine_utils.c b/ext/symengine/symengine_utils.c index 0234628..abc3df4 100644 --- a/ext/symengine/symengine_utils.c +++ b/ext/symengine/symengine_utils.c @@ -40,10 +40,19 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) { sympify(real, real_basic); sympify(imag, imag_basic); - complex_set(cbasic_operand2, real_basic, imag_basic); + + basic_struct *const_I = basic_new_heap(); + basic_struct *imag_part = basic_new_heap(); + + basic_const_I(const_I); + basic_mul(imag_part, const_I, imag_basic); + basic_add(cbasic_operand2, imag_part, real_basic); basic_free_heap(real_basic); basic_free_heap(imag_basic); + basic_free_heap(const_I); + basic_free_heap(imag_part); + break; case T_DATA: From cb283838627f61dc28604cae0523528fe457021e Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 15:54:23 +0530 Subject: [PATCH 12/26] Tests edited to support versions <= 2.0 --- spec/complex_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/complex_spec.rb b/spec/complex_spec.rb index b4214bc..6a93550 100644 --- a/spec/complex_spec.rb +++ b/spec/complex_spec.rb @@ -13,7 +13,7 @@ end context 'with a Ruby Integer as input' do it 'returns an instance of SymEngine::Integer class' do - a = 2 + 0i; + a = Complex(2, 0); a = SymEngine::sympify(a) expect(a).to be_a SymEngine::Integer expect(a.to_s).to eq('2') From fa1fbe560e123a59ffd1b537228b3dfea43df888 Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 16:56:15 +0530 Subject: [PATCH 13/26] Minor corrections --- ext/symengine/symengine_utils.c | 26 +++++++++++++------------- spec/complex_spec.rb | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ext/symengine/symengine_utils.c b/ext/symengine/symengine_utils.c index abc3df4..50a0ab7 100644 --- a/ext/symengine/symengine_utils.c +++ b/ext/symengine/symengine_utils.c @@ -34,24 +34,21 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) { real = rb_funcall(operand2, rb_intern("real"), 0, NULL); imag = rb_funcall(operand2, rb_intern("imaginary"), 0, NULL); - basic_struct *real_basic = basic_new_heap(); - basic_struct *imag_basic = basic_new_heap(); + basic real_basic; + basic imag_basic; + + basic_new_stack(real_basic); + basic_new_stack(imag_basic); sympify(real, real_basic); sympify(imag, imag_basic); - - basic_struct *const_I = basic_new_heap(); - basic_struct *imag_part = basic_new_heap(); - - basic_const_I(const_I); - basic_mul(imag_part, const_I, imag_basic); - basic_add(cbasic_operand2, imag_part, real_basic); + basic_const_I(cbasic_operand2); + basic_mul(cbasic_operand2, cbasic_operand2, imag_basic); + basic_add(cbasic_operand2, cbasic_operand2, real_basic); - basic_free_heap(real_basic); - basic_free_heap(imag_basic); - basic_free_heap(const_I); - basic_free_heap(imag_part); + basic_free_stack(real_basic); + basic_free_stack(imag_basic); break; @@ -59,6 +56,7 @@ void sympify(VALUE operand2, basic_struct *cbasic_operand2) { Data_Get_Struct(operand2, basic_struct, temp); basic_assign(cbasic_operand2, temp); break; + } } @@ -72,6 +70,8 @@ VALUE Klass_of_Basic(const basic_struct *basic_ptr) { return c_rational; case SYMENGINE_COMPLEX: return c_complex; + case SYMENGINE_COMPLEX_DOUBLE: + return c_complex_double; case SYMENGINE_CONSTANT: return c_constant; case SYMENGINE_ADD: diff --git a/spec/complex_spec.rb b/spec/complex_spec.rb index 6a93550..9f3c965 100644 --- a/spec/complex_spec.rb +++ b/spec/complex_spec.rb @@ -7,7 +7,7 @@ it 'returns an instance of SymEngine::Complex class' do a = Complex(2, 3) a = SymEngine::sympify(a) - expect(a).to be_a SymEngine::Complex + expect(a).to be_an_instance_of SymEngine::Complex expect(a.to_s).to eq('2 + 3*I') end end @@ -15,7 +15,7 @@ it 'returns an instance of SymEngine::Integer class' do a = Complex(2, 0); a = SymEngine::sympify(a) - expect(a).to be_a SymEngine::Integer + expect(a).to be_an_instance_of SymEngine::Integer expect(a.to_s).to eq('2') end end From 7def8b6f2b8feb190b92d16f79a90395a06b1d93 Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 17:16:37 +0530 Subject: [PATCH 14/26] to_c method --- lib/symengine.rb | 1 + lib/symengine/complex.rb | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 lib/symengine/complex.rb diff --git a/lib/symengine.rb b/lib/symengine.rb index 31e5f3e..06ebd31 100644 --- a/lib/symengine.rb +++ b/lib/symengine.rb @@ -35,3 +35,4 @@ def symbols ary_or_string, *params require 'symengine/iruby' require 'symengine/basic' require 'symengine/integer' +require 'symengine/complex' diff --git a/lib/symengine/complex.rb b/lib/symengine/complex.rb new file mode 100644 index 0000000..18896f9 --- /dev/null +++ b/lib/symengine/complex.rb @@ -0,0 +1,7 @@ +module SymEngine + class Complex + def to_c + self.to_s.sub('I', 'i').sub('*','').gsub(' ','').to_c + end + end +end From 9ddc2c625f81653f8e750106c61c7f3696ad2cbb Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Wed, 25 May 2016 17:51:27 +0530 Subject: [PATCH 15/26] classes for Complex_double --- ext/symengine/symengine.c | 4 ++++ ext/symengine/symengine.h | 1 + 2 files changed, 5 insertions(+) diff --git a/ext/symengine/symengine.c b/ext/symengine/symengine.c index 909eb99..e29d394 100644 --- a/ext/symengine/symengine.c +++ b/ext/symengine/symengine.c @@ -67,6 +67,10 @@ void Init_symengine() { c_complex = rb_define_class_under(m_symengine, "Complex", c_basic); rb_define_alloc_func(c_complex, cbasic_alloc); + //ComplexDouble class + c_complex_double = rb_define_class_under(m_symengine, "ComplexDouble", c_basic); + rb_define_alloc_func(c_complex_double, cbasic_alloc); + //Constant class c_constant = rb_define_class_under(m_symengine, "Constant", c_basic); diff --git a/ext/symengine/symengine.h b/ext/symengine/symengine.h index 2fed187..b50beb1 100644 --- a/ext/symengine/symengine.h +++ b/ext/symengine/symengine.h @@ -12,6 +12,7 @@ VALUE c_symbol; VALUE c_integer; VALUE c_rational; VALUE c_complex; +VALUE c_complex_double; VALUE c_constant; VALUE c_add; VALUE c_mul; From 22cff510b695d98118755c549a707e4358b51eb4 Mon Sep 17 00:00:00 2001 From: Rajith Vidanaarachchi Date: Thu, 26 May 2016 11:10:58 +0530 Subject: [PATCH 16/26] alias S for sympify --- ext/symengine/symengine.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/symengine/symengine.c b/ext/symengine/symengine.c index e29d394..c664d4c 100644 --- a/ext/symengine/symengine.c +++ b/ext/symengine/symengine.c @@ -47,6 +47,7 @@ void Init_symengine() { //Sympify as a Module Level Function rb_define_module_function(m_symengine, "sympify", cutils_sympify, 1); + rb_define_module_function(m_symengine, "S", cutils_sympify, 1); //Symbol class c_symbol = rb_define_class_under(m_symengine, "Symbol", c_basic); From d0da640bda5a66caca37270ade5fd45298d8c5ad Mon Sep 17 00:00:00 2001 From: rajithv Date: Thu, 26 May 2016 17:50:19 +0530 Subject: [PATCH 17/26] Real part and Imaginary part wrappers --- ext/symengine/CMakeLists.txt | 1 + ext/symengine/ruby_complex.c | 37 +++++++++++++++++++++++++++++++++ ext/symengine/ruby_complex.h | 13 ++++++++++++ ext/symengine/symengine.c | 3 +++ lib/symengine/complex.rb | 2 +- spec/complex_spec.rb | 40 +++++++++++++++++++++++++++++++++++- symengine_version.txt | 3 +-- 7 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 ext/symengine/ruby_complex.c create mode 100644 ext/symengine/ruby_complex.h diff --git a/ext/symengine/CMakeLists.txt b/ext/symengine/CMakeLists.txt index d9efad8..55c8ea1 100644 --- a/ext/symengine/CMakeLists.txt +++ b/ext/symengine/CMakeLists.txt @@ -2,6 +2,7 @@ set(RUBY_WRAPPER_SRC ruby_basic.c ruby_symbol.c ruby_integer.c + ruby_complex.c ruby_constant.c ruby_function.c ruby_ntheory.c diff --git a/ext/symengine/ruby_complex.c b/ext/symengine/ruby_complex.c new file mode 100644 index 0000000..18ce16f --- /dev/null +++ b/ext/symengine/ruby_complex.c @@ -0,0 +1,37 @@ +#include "ruby_complex.h" + +VALUE ccomplex_real_part(VALUE self) { + basic_struct *c_result = basic_new_heap(); + + basic cbasic_operand; + basic_new_stack(cbasic_operand); + + VALUE result; + + sympify(self, cbasic_operand); + complex_real_part(c_result, cbasic_operand); + + result = Data_Wrap_Struct(Klass_of_Basic(c_result), NULL, cbasic_free_heap, c_result); + + basic_free_stack(cbasic_operand); + + return result; +} + +VALUE ccomplex_imaginary_part(VALUE self) { + basic_struct *c_result = basic_new_heap(); + + basic cbasic_operand; + basic_new_stack(cbasic_operand); + + VALUE result; + + sympify(self, cbasic_operand); + complex_imaginary_part(c_result, cbasic_operand); + + result = Data_Wrap_Struct(Klass_of_Basic(c_result), NULL, cbasic_free_heap, c_result); + + basic_free_stack(cbasic_operand); + + return result; +} diff --git a/ext/symengine/ruby_complex.h b/ext/symengine/ruby_complex.h new file mode 100644 index 0000000..7df00a7 --- /dev/null +++ b/ext/symengine/ruby_complex.h @@ -0,0 +1,13 @@ +#ifndef RUBY_COMPLEX_H_ +#define RUBY_COMPLEX_H_ + +#include +#include + +#include "symengine.h" +#include "symengine_utils.h" + +VALUE ccomplex_real_part(VALUE self); +VALUE ccomplex_imaginary_part(VALUE self); + +#endif //RUBY_COMPLEX_H_ diff --git a/ext/symengine/symengine.c b/ext/symengine/symengine.c index c664d4c..de3584a 100644 --- a/ext/symengine/symengine.c +++ b/ext/symengine/symengine.c @@ -3,6 +3,7 @@ #include "ruby_symbol.h" #include "ruby_integer.h" #include "ruby_constant.h" +#include "ruby_complex.h" #include "ruby_function.h" #include "ruby_ntheory.h" #include "ruby_utils.h" @@ -67,6 +68,8 @@ void Init_symengine() { //Complex class c_complex = rb_define_class_under(m_symengine, "Complex", c_basic); rb_define_alloc_func(c_complex, cbasic_alloc); + rb_define_method(c_complex, "real", ccomplex_real_part, 0); + rb_define_method(c_complex, "imaginary", ccomplex_imaginary_part, 0); //ComplexDouble class c_complex_double = rb_define_class_under(m_symengine, "ComplexDouble", c_basic); diff --git a/lib/symengine/complex.rb b/lib/symengine/complex.rb index 18896f9..f71f6b0 100644 --- a/lib/symengine/complex.rb +++ b/lib/symengine/complex.rb @@ -4,4 +4,4 @@ def to_c self.to_s.sub('I', 'i').sub('*','').gsub(' ','').to_c end end -end +end diff --git a/spec/complex_spec.rb b/spec/complex_spec.rb index 9f3c965..9ef4711 100644 --- a/spec/complex_spec.rb +++ b/spec/complex_spec.rb @@ -13,12 +13,50 @@ end context 'with a Ruby Integer as input' do it 'returns an instance of SymEngine::Integer class' do - a = Complex(2, 0); + a = Complex(2, 0) a = SymEngine::sympify(a) expect(a).to be_an_instance_of SymEngine::Integer expect(a.to_s).to eq('2') end end + context 'Obtaining the integer real part' do + it 'returns an instance of SymEngine::Integer class' do + a = Complex(2, 7) + a = SymEngine::S(a) + a = a.real + expect(a).to be_an_instance_of SymEngine::Integer + expect(a.to_s).to eq('2'); + end + end + context 'Obtaining the integer imaginary part' do + it 'returns an instance of SymEngine::Integer class' do + a = Complex(2, 7) + a = SymEngine::S(a) + a = a.imaginary + expect(a).to be_an_instance_of SymEngine::Integer + expect(a.to_s).to eq('7'); + end + end + context 'Obtaining the rational real part ' do + it 'returns an instance of SymEngine::Rational class' do + a = Rational('5/4') + a = Complex(a, 7) + a = SymEngine::S(a) + a = a.real + expect(a).to be_an_instance_of SymEngine::Rational + expect(a.to_s).to eq('5/4'); + end + end + context 'Obtaining the rational imaginary part' do + it 'returns an instance of SymEngine::Integer class' do + a = Rational('5/4') + a = Complex(2, a) + a = SymEngine::S(a) + a = a.imaginary + expect(a).to be_an_instance_of SymEngine::Rational + expect(a.to_s).to eq('5/4'); + end + end end end end diff --git a/symengine_version.txt b/symengine_version.txt index 642392c..eb3dc2d 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1,2 +1 @@ -5e88e62b42c38200573eecf688d90b46beb38a77 - +382a917700e6c6116e025e64baff66d0668c64f2 From 038aace64caff749e89924944f5e3c5488d587b9 Mon Sep 17 00:00:00 2001 From: rajithv Date: Thu, 26 May 2016 18:08:31 +0530 Subject: [PATCH 18/26] renamed sympify->convert and short form to SymEngine() --- ext/symengine/symengine.c | 5 +++-- spec/complex_spec.rb | 12 ++++++------ spec/rational_spec.rb | 14 +++++++------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/ext/symengine/symengine.c b/ext/symengine/symengine.c index de3584a..02c35d5 100644 --- a/ext/symengine/symengine.c +++ b/ext/symengine/symengine.c @@ -22,6 +22,7 @@ VALUE msymengine_ascii_art(VALUE self) { } void Init_symengine() { + m_symengine = rb_define_module("SymEngine"); rb_define_singleton_method(m_symengine, "ascii_art", msymengine_ascii_art, 0); @@ -47,8 +48,8 @@ void Init_symengine() { rb_define_method(c_basic, "coerce", cbasic_coerce, 1); //Sympify as a Module Level Function - rb_define_module_function(m_symengine, "sympify", cutils_sympify, 1); - rb_define_module_function(m_symengine, "S", cutils_sympify, 1); + rb_define_module_function(m_symengine, "convert", cutils_sympify, 1); + rb_define_global_function("SymEngine", cutils_sympify, 1); //Symbol class c_symbol = rb_define_class_under(m_symengine, "Symbol", c_basic); diff --git a/spec/complex_spec.rb b/spec/complex_spec.rb index 9ef4711..f4418d9 100644 --- a/spec/complex_spec.rb +++ b/spec/complex_spec.rb @@ -6,7 +6,7 @@ context 'with a Ruby Complex object as input' do it 'returns an instance of SymEngine::Complex class' do a = Complex(2, 3) - a = SymEngine::sympify(a) + a = SymEngine::convert(a) expect(a).to be_an_instance_of SymEngine::Complex expect(a.to_s).to eq('2 + 3*I') end @@ -14,7 +14,7 @@ context 'with a Ruby Integer as input' do it 'returns an instance of SymEngine::Integer class' do a = Complex(2, 0) - a = SymEngine::sympify(a) + a = SymEngine::convert(a) expect(a).to be_an_instance_of SymEngine::Integer expect(a.to_s).to eq('2') end @@ -22,7 +22,7 @@ context 'Obtaining the integer real part' do it 'returns an instance of SymEngine::Integer class' do a = Complex(2, 7) - a = SymEngine::S(a) + a = SymEngine::convert(a) a = a.real expect(a).to be_an_instance_of SymEngine::Integer expect(a.to_s).to eq('2'); @@ -31,7 +31,7 @@ context 'Obtaining the integer imaginary part' do it 'returns an instance of SymEngine::Integer class' do a = Complex(2, 7) - a = SymEngine::S(a) + a = SymEngine::convert(a) a = a.imaginary expect(a).to be_an_instance_of SymEngine::Integer expect(a.to_s).to eq('7'); @@ -41,7 +41,7 @@ it 'returns an instance of SymEngine::Rational class' do a = Rational('5/4') a = Complex(a, 7) - a = SymEngine::S(a) + a = SymEngine::convert(a) a = a.real expect(a).to be_an_instance_of SymEngine::Rational expect(a.to_s).to eq('5/4'); @@ -51,7 +51,7 @@ it 'returns an instance of SymEngine::Integer class' do a = Rational('5/4') a = Complex(2, a) - a = SymEngine::S(a) + a = SymEngine::convert(a) a = a.imaginary expect(a).to be_an_instance_of SymEngine::Rational expect(a.to_s).to eq('5/4'); diff --git a/spec/rational_spec.rb b/spec/rational_spec.rb index aee3ef9..a756071 100644 --- a/spec/rational_spec.rb +++ b/spec/rational_spec.rb @@ -6,7 +6,7 @@ context 'with a Ruby Rational object as input' do it 'returns an instance of SymEngine::Rational class' do a = Rational('2/3') - a = SymEngine::sympify(a) + a = SymEngine::convert(a) expect(a).to be_a SymEngine::Rational expect(a.to_s).to eq('2/3') end @@ -14,7 +14,7 @@ context 'with a Ruby Integer as input' do it 'returns an instance of SymEngine::Integer class' do a = Rational('2/1') - a = SymEngine::sympify(a) + a = SymEngine::convert(a) expect(a).to be_a SymEngine::Integer expect(a.to_s).to eq('2') end @@ -22,7 +22,7 @@ context 'with a Ruby Integer (x/x) as input' do it 'returns an instance of SymEngine::Integer class' do a = Rational('5/5') - a = SymEngine::sympify(a) + a = SymEngine::convert(a) expect(a).to be_a SymEngine::Integer expect(a.to_s).to eq('1') end @@ -39,13 +39,13 @@ it 'succeeds with commutative operations' do c = @a * @b expect(c).to be_a SymEngine::Basic - expect(c).to eq(SymEngine::sympify(@b) * @a) + expect(c).to eq(SymEngine::convert(@b) * @a) end it 'succeeds with non commutative operations' do c = @a / @b expect(c).to be_a SymEngine::Basic - expect(c).to eq(@a / SymEngine::sympify(@b)) + expect(c).to eq(@a / SymEngine::convert(@b)) end end @@ -53,13 +53,13 @@ it 'succeeds with commutative operations' do c = @b * @a expect(c).to be_a SymEngine::Basic - expect(c).to eq(@a * SymEngine::sympify(@b)) + expect(c).to eq(@a * SymEngine::convert(@b)) end it 'succeeds with non commutative operations' do c = @b / @a expect(c).to be_a SymEngine::Basic - expect(c).to eq(SymEngine::sympify(@b) / @a) + expect(c).to eq(SymEngine::convert(@b) / @a) end end end From a4b43d44e9a57635dd28681a16cd37d512680b47 Mon Sep 17 00:00:00 2001 From: rajithv Date: Thu, 26 May 2016 22:50:28 +0530 Subject: [PATCH 19/26] SymEngine version update --- symengine_version.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index eb3dc2d..4aaed59 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1,2 @@ -382a917700e6c6116e025e64baff66d0668c64f2 +9ea0bb65e994b6a0666fadece76e876bdcef9b6d + From a219d58d194fbf054cd0489f251e1ec9c2eec46d Mon Sep 17 00:00:00 2001 From: rajithv Date: Thu, 26 May 2016 22:50:28 +0530 Subject: [PATCH 20/26] SymEngine version update --- symengine_version.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index eb3dc2d..275ea94 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1,2 @@ -382a917700e6c6116e025e64baff66d0668c64f2 +5a877cbc951dbc2bd3cdd5f4758cae5b13acf0fd + From 81ade4c2e038fc63cf09162be866a22468d64daf Mon Sep 17 00:00:00 2001 From: rajithv Date: Sat, 28 May 2016 15:26:24 +0530 Subject: [PATCH 21/26] Complex Spec --- spec/complex_spec.rb | 101 +++++++++++++++++++----------------------- symengine_version.txt | 2 +- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/spec/complex_spec.rb b/spec/complex_spec.rb index f4418d9..5422227 100644 --- a/spec/complex_spec.rb +++ b/spec/complex_spec.rb @@ -1,62 +1,51 @@ -require 'spec_helper' - -describe SymEngine do - describe SymEngine::Complex do - describe '.new' do - context 'with a Ruby Complex object as input' do - it 'returns an instance of SymEngine::Complex class' do - a = Complex(2, 3) - a = SymEngine::convert(a) - expect(a).to be_an_instance_of SymEngine::Complex - expect(a.to_s).to eq('2 + 3*I') - end - end - context 'with a Ruby Integer as input' do - it 'returns an instance of SymEngine::Integer class' do - a = Complex(2, 0) - a = SymEngine::convert(a) - expect(a).to be_an_instance_of SymEngine::Integer - expect(a.to_s).to eq('2') - end - end - context 'Obtaining the integer real part' do - it 'returns an instance of SymEngine::Integer class' do - a = Complex(2, 7) - a = SymEngine::convert(a) - a = a.real - expect(a).to be_an_instance_of SymEngine::Integer - expect(a.to_s).to eq('2'); - end +describe SymEngine::Complex do + context '#initialize' do + context 'with a Complex' do + subject { SymEngine(Complex(2, 3)) } + + it { is_expected.to be_a SymEngine::Complex } + its(:to_s) { is_expected.to eq '2 + 3*I' } + end + + context 'with an integer' do + subject { SymEngine(Complex(2, 0)) } + + it { is_expected.to be_a SymEngine::Integer } + its(:to_s) { is_expected.to eq '2' } + end + end + + context 'real_part and imaginary_part' do + let(:a) { SymEngine(Complex(Rational('2/7'), Rational('3/8'))) } + let(:b) { SymEngine(Complex(2, 3)) } + + context 'real_part' do + context 'using SymEngine Rationals' do + subject { a.real } + it { is_expected.to be_a SymEngine::Rational } + its(:to_s) { is_expected.to eq '2/7' } end - context 'Obtaining the integer imaginary part' do - it 'returns an instance of SymEngine::Integer class' do - a = Complex(2, 7) - a = SymEngine::convert(a) - a = a.imaginary - expect(a).to be_an_instance_of SymEngine::Integer - expect(a.to_s).to eq('7'); - end + + context 'using SymEngine Integers' do + subject { b.real } + it { is_expected.to be_a SymEngine::Integer } + its(:to_s) { is_expected.to eq '2' } end - context 'Obtaining the rational real part ' do - it 'returns an instance of SymEngine::Rational class' do - a = Rational('5/4') - a = Complex(a, 7) - a = SymEngine::convert(a) - a = a.real - expect(a).to be_an_instance_of SymEngine::Rational - expect(a.to_s).to eq('5/4'); - end + end + + context 'imaginary_part' do + context 'using SymEngine Rationals' do + subject { a.imaginary } + it { is_expected.to be_a SymEngine::Rational } + its(:to_s) { is_expected.to eq '3/8' } end - context 'Obtaining the rational imaginary part' do - it 'returns an instance of SymEngine::Integer class' do - a = Rational('5/4') - a = Complex(2, a) - a = SymEngine::convert(a) - a = a.imaginary - expect(a).to be_an_instance_of SymEngine::Rational - expect(a.to_s).to eq('5/4'); - end + + context 'using SymEngine Integers' do + subject { b.imaginary } + it { is_expected.to be_a SymEngine::Integer } + its(:to_s) { is_expected.to eq '3' } end - end + end end end + diff --git a/symengine_version.txt b/symengine_version.txt index 370c234..bc0e52b 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1,2 +1,2 @@ -745b4e4d4d429aa6c08fd561676ef4d5920ada0f +3f58acc1246661323b1daf2adc3f9fa6a8762df4 From e9162e0866a12c400d8fbb145f04c14e6aacfe94 Mon Sep 17 00:00:00 2001 From: rajithv Date: Sat, 28 May 2016 16:05:51 +0530 Subject: [PATCH 22/26] Tests for convert() and SymEngine() --- spec/symengine_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/symengine_spec.rb b/spec/symengine_spec.rb index c3782d9..0f1017a 100644 --- a/spec/symengine_spec.rb +++ b/spec/symengine_spec.rb @@ -4,4 +4,19 @@ expect(SymEngine.ascii_art).to_not be_empty end end + + describe 'convert' do + subject { SymEngine::convert(Complex(2, 3)) } + + it { is_expected.to be_a SymEngine::Complex } + its(:to_s) { is_expected.to eq '2 + 3*I' } + end + + describe 'SymEngine()' do + subject { SymEngine(Rational('1/3')) } + + it { is_expected.to be_a SymEngine::Rational } + its(:to_s) { is_expected.to eq '1/3' } + end + end From 7ddd68ef2da30087a99f17764b87afafbacd8f9a Mon Sep 17 00:00:00 2001 From: rajithv Date: Sat, 28 May 2016 16:50:33 +0530 Subject: [PATCH 23/26] Changed I from Constant to Complex --- ext/symengine/ruby_constant.c | 9 ++++++++- spec/constant_spec.rb | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ext/symengine/ruby_constant.c b/ext/symengine/ruby_constant.c index 95bba36..a5f810e 100644 --- a/ext/symengine/ruby_constant.c +++ b/ext/symengine/ruby_constant.c @@ -24,5 +24,12 @@ VALUE cconstant_euler_gamma() { } VALUE cconstant_i() { - return cconstant_const(basic_const_I); + basic_struct *cresult; + VALUE result; + + cresult = basic_new_heap(); + basic_const_I(cresult); + + result = Data_Wrap_Struct(c_complex, NULL, cbasic_free_heap, cresult); + return result; } diff --git a/spec/constant_spec.rb b/spec/constant_spec.rb index 96320dc..3bcfa70 100644 --- a/spec/constant_spec.rb +++ b/spec/constant_spec.rb @@ -46,7 +46,7 @@ describe '#i' do subject(:i) { SymEngine::I } - it { is_expected.to be_a SymEngine::Constant } + it { is_expected.to be_a SymEngine::Complex } context 'when squared' do subject { i * i} From e96d9341ca8210f86bc0009acf8afb5e478b0d2e Mon Sep 17 00:00:00 2001 From: rajithv Date: Sat, 28 May 2016 19:13:49 +0530 Subject: [PATCH 24/26] Fixing errors --- lib/symengine/complex.rb | 2 +- spec/complex_spec.rb | 2 +- spec/rational_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/symengine/complex.rb b/lib/symengine/complex.rb index f71f6b0..26f9f34 100644 --- a/lib/symengine/complex.rb +++ b/lib/symengine/complex.rb @@ -1,7 +1,7 @@ module SymEngine class Complex def to_c - self.to_s.sub('I', 'i').sub('*','').gsub(' ','').to_c + to_s.tr('I', 'i').tr('*','').tr(' ','').to_c end end end diff --git a/spec/complex_spec.rb b/spec/complex_spec.rb index 5422227..ee29ddb 100644 --- a/spec/complex_spec.rb +++ b/spec/complex_spec.rb @@ -1,5 +1,5 @@ describe SymEngine::Complex do - context '#initialize' do + context 'Convert to SymEngine types' do context 'with a Complex' do subject { SymEngine(Complex(2, 3)) } diff --git a/spec/rational_spec.rb b/spec/rational_spec.rb index fa8ba3c..a9771d5 100644 --- a/spec/rational_spec.rb +++ b/spec/rational_spec.rb @@ -1,5 +1,5 @@ describe SymEngine::Rational do - context '#initialize' do + context 'Convert to SymEngine types' do context 'with a Rational' do subject { SymEngine(Rational('2/3')) } From 52e1870bd176032991185a4890da7a5e93388b9c Mon Sep 17 00:00:00 2001 From: rajithv Date: Sat, 28 May 2016 21:45:25 +0530 Subject: [PATCH 25/26] Fixing further errors --- ext/symengine/ruby_complex.c | 32 ++------------------------------ ext/symengine/ruby_constant.c | 19 ++++++------------- ext/symengine/ruby_constant.h | 2 +- 3 files changed, 9 insertions(+), 44 deletions(-) diff --git a/ext/symengine/ruby_complex.c b/ext/symengine/ruby_complex.c index 18ce16f..eba2437 100644 --- a/ext/symengine/ruby_complex.c +++ b/ext/symengine/ruby_complex.c @@ -1,37 +1,9 @@ #include "ruby_complex.h" VALUE ccomplex_real_part(VALUE self) { - basic_struct *c_result = basic_new_heap(); - - basic cbasic_operand; - basic_new_stack(cbasic_operand); - - VALUE result; - - sympify(self, cbasic_operand); - complex_real_part(c_result, cbasic_operand); - - result = Data_Wrap_Struct(Klass_of_Basic(c_result), NULL, cbasic_free_heap, c_result); - - basic_free_stack(cbasic_operand); - - return result; + return function_onearg(complex_real_part, self); } VALUE ccomplex_imaginary_part(VALUE self) { - basic_struct *c_result = basic_new_heap(); - - basic cbasic_operand; - basic_new_stack(cbasic_operand); - - VALUE result; - - sympify(self, cbasic_operand); - complex_imaginary_part(c_result, cbasic_operand); - - result = Data_Wrap_Struct(Klass_of_Basic(c_result), NULL, cbasic_free_heap, c_result); - - basic_free_stack(cbasic_operand); - - return result; + return function_onearg(complex_imaginary_part, self); } diff --git a/ext/symengine/ruby_constant.c b/ext/symengine/ruby_constant.c index a5f810e..8f25fe0 100644 --- a/ext/symengine/ruby_constant.c +++ b/ext/symengine/ruby_constant.c @@ -1,35 +1,28 @@ #include "ruby_constant.h" -VALUE cconstant_const(void (*cwfunc_ptr)(basic_struct*)) { +VALUE cconstant_const(void (*cwfunc_ptr)(basic_struct*), VALUE klass) { basic_struct *cresult; VALUE result; cresult = basic_new_heap(); cwfunc_ptr(cresult); - result = Data_Wrap_Struct(c_constant, NULL, cbasic_free_heap, cresult); + result = Data_Wrap_Struct(klass, NULL, cbasic_free_heap, cresult); return result; } VALUE cconstant_pi() { - return cconstant_const(basic_const_pi); + return cconstant_const(basic_const_pi, c_constant); } VALUE cconstant_e() { - return cconstant_const(basic_const_E); + return cconstant_const(basic_const_E, c_constant); } VALUE cconstant_euler_gamma() { - return cconstant_const(basic_const_EulerGamma); + return cconstant_const(basic_const_EulerGamma, c_constant); } VALUE cconstant_i() { - basic_struct *cresult; - VALUE result; - - cresult = basic_new_heap(); - basic_const_I(cresult); - - result = Data_Wrap_Struct(c_complex, NULL, cbasic_free_heap, cresult); - return result; + return cconstant_const(basic_const_I, c_complex); } diff --git a/ext/symengine/ruby_constant.h b/ext/symengine/ruby_constant.h index c1032da..a89377e 100644 --- a/ext/symengine/ruby_constant.h +++ b/ext/symengine/ruby_constant.h @@ -7,7 +7,7 @@ #include "symengine.h" #include "symengine_utils.h" -VALUE cconstant_const(void (*cwfunc_ptr)(basic_struct*)); +VALUE cconstant_const(void (*cwfunc_ptr)(basic_struct*), VALUE klass); VALUE cconstant_pi(); From 5802cf73bdb51720e82b43024c390834c8ad3eb6 Mon Sep 17 00:00:00 2001 From: rajithv Date: Sat, 28 May 2016 22:56:14 +0530 Subject: [PATCH 26/26] minor change --- lib/symengine/complex.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/symengine/complex.rb b/lib/symengine/complex.rb index 26f9f34..3903ebd 100644 --- a/lib/symengine/complex.rb +++ b/lib/symengine/complex.rb @@ -1,7 +1,7 @@ module SymEngine class Complex def to_c - to_s.tr('I', 'i').tr('*','').tr(' ','').to_c + to_s.tr('I', 'i').delete(' *').to_c end end end