Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f9b0661
Basic structure for complex
rajithv May 23, 2016
b4af3b0
Rational spec changed to reflect required changes
rajithv May 23, 2016
316a9c1
Adding spec for Complex
rajithv May 23, 2016
88b302f
Exposed sympify to Ruby
rajithv May 24, 2016
dbd072d
Expose sympify to Ruby - correction
rajithv May 24, 2016
d1498f4
Added complex to klass of basic & sympify
rajithv May 24, 2016
62d67ed
Removed inits of Complex and Rational. This fixes #19 and fixes #21
rajithv May 24, 2016
505618a
Rational Spec updated to replace .new with Sympify
rajithv May 24, 2016
dd79ff0
Ruby wrapper for i, the constant
rajithv May 24, 2016
0f4694a
Complex numbers done
rajithv May 24, 2016
6633cb4
Edited complex to accept not only rational
rajithv May 25, 2016
cb28383
Tests edited to support versions <= 2.0
rajithv May 25, 2016
fa1fbe5
Minor corrections
rajithv May 25, 2016
7def8b6
to_c method
rajithv May 25, 2016
9ddc2c6
classes for Complex_double
rajithv May 25, 2016
22cff51
alias S for sympify
rajithv May 26, 2016
d0da640
Real part and Imaginary part wrappers
rajithv May 26, 2016
038aace
renamed sympify->convert and short form to SymEngine()
rajithv May 26, 2016
a4b43d4
SymEngine version update
rajithv May 26, 2016
a219d58
SymEngine version update
rajithv May 26, 2016
7953c83
Merge branch 'master' of http://github.com/symengine/symengine.rb int…
rajithv May 28, 2016
417eb97
Merge branch 'doubles' into complex
rajithv May 28, 2016
1246cb2
Merge branch 'master' of http://github.com/symengine/symengine.rb int…
rajithv May 28, 2016
81ade4c
Complex Spec
rajithv May 28, 2016
e9162e0
Tests for convert() and SymEngine()
rajithv May 28, 2016
7ddd68e
Changed I from Constant to Complex
rajithv May 28, 2016
e96d934
Fixing errors
rajithv May 28, 2016
52e1870
Fixing further errors
rajithv May 28, 2016
5802cf7
minor change
rajithv May 28, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ext/symengine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ 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
ruby_utils.c
symengine_utils.c
symengine.c
)
Expand Down
9 changes: 9 additions & 0 deletions ext/symengine/ruby_complex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "ruby_complex.h"

VALUE ccomplex_real_part(VALUE self) {
return function_onearg(complex_real_part, self);
}

VALUE ccomplex_imaginary_part(VALUE self) {
return function_onearg(complex_imaginary_part, self);
}
13 changes: 13 additions & 0 deletions ext/symengine/ruby_complex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef RUBY_COMPLEX_H_
#define RUBY_COMPLEX_H_

#include <ruby.h>
#include <symengine/cwrapper.h>

#include "symengine.h"
#include "symengine_utils.h"

VALUE ccomplex_real_part(VALUE self);
VALUE ccomplex_imaginary_part(VALUE self);

#endif //RUBY_COMPLEX_H_
14 changes: 9 additions & 5 deletions ext/symengine/ruby_constant.c
Original file line number Diff line number Diff line change
@@ -1,24 +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() {
return cconstant_const(basic_const_I, c_complex);
}
4 changes: 3 additions & 1 deletion ext/symengine/ruby_constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
#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();

VALUE cconstant_e();

VALUE cconstant_euler_gamma();

VALUE cconstant_i();

#endif //RUBY_CONSTANTS_H_
23 changes: 0 additions & 23 deletions ext/symengine/ruby_rational.c

This file was deleted.

8 changes: 0 additions & 8 deletions ext/symengine/ruby_rational.h

This file was deleted.

15 changes: 15 additions & 0 deletions ext/symengine/ruby_utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "ruby_utils.h"

VALUE cutils_sympify(VALUE self, VALUE operand) {

VALUE result;

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 result;
}

9 changes: 9 additions & 0 deletions ext/symengine/ruby_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef RUBY_UTILS_H_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have this in symengine_utils.h right? No need of a new file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking to keep the functions for C in symengine_utils.h, while having the functions exposed in Ruby in ruby_utils.h (as per the convention of other .h files)...

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay

#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_
21 changes: 19 additions & 2 deletions ext/symengine/symengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
#include "ruby_basic.h"
#include "ruby_symbol.h"
#include "ruby_integer.h"
#include "ruby_rational.h"
#include "ruby_constant.h"
#include "ruby_complex.h"
#include "ruby_function.h"
#include "ruby_ntheory.h"
#include "ruby_utils.h"
#include "symengine_utils.h"
#include "symengine.h"

///////////////////
Expand All @@ -20,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);

Expand All @@ -44,6 +47,10 @@ 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, "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);
rb_define_alloc_func(c_symbol, cbasic_alloc);
Expand All @@ -58,7 +65,16 @@ 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, "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);
rb_define_alloc_func(c_complex_double, cbasic_alloc);

//Constant class
c_constant = rb_define_class_under(m_symengine, "Constant", c_basic);
Expand All @@ -67,6 +83,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);
Expand Down
2 changes: 2 additions & 0 deletions ext/symengine/symengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ VALUE c_basic;
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;
Expand Down
29 changes: 29 additions & 0 deletions ext/symengine/symengine_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
#include "symengine.h"

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:
Expand All @@ -28,10 +30,33 @@ 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("imaginary"), 0, NULL);

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_const_I(cbasic_operand2);
basic_mul(cbasic_operand2, cbasic_operand2, imag_basic);
basic_add(cbasic_operand2, cbasic_operand2, real_basic);

basic_free_stack(real_basic);
basic_free_stack(imag_basic);

break;

case T_DATA:
Data_Get_Struct(operand2, basic_struct, temp);
basic_assign(cbasic_operand2, temp);
break;

}
}

Expand All @@ -43,6 +68,10 @@ 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_COMPLEX_DOUBLE:
return c_complex_double;
case SYMENGINE_CONSTANT:
return c_constant;
case SYMENGINE_ADD:
Expand Down
1 change: 1 addition & 0 deletions lib/symengine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ def symbols ary_or_string, *params
require 'symengine/iruby'
require 'symengine/basic'
require 'symengine/integer'
require 'symengine/complex'
7 changes: 7 additions & 0 deletions lib/symengine/complex.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module SymEngine
class Complex
def to_c
to_s.tr('I', 'i').delete(' *').to_c
end
end
end
51 changes: 51 additions & 0 deletions spec/complex_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
describe SymEngine::Complex do
context 'Convert to SymEngine types' 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 'using SymEngine Integers' do
subject { b.real }
it { is_expected.to be_a SymEngine::Integer }
its(:to_s) { is_expected.to eq '2' }
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 '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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests for the other member functions of SymEngine::Complex should be added(with xit) that are allowed to fail for now before moving onto the other PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are real_part() and imaginary_part() right? Or are there any other member functions which should be checked? like addition etc.


13 changes: 13 additions & 0 deletions spec/constant_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,17 @@
its(:to_s) { is_expected.to eq 'x + E' }
end
end

describe '#i' do
subject(:i) { SymEngine::I }

it { is_expected.to be_a SymEngine::Complex }

context 'when squared' do
subject { i * i}
it { is_expected.to be_a SymEngine::Basic }
its(:to_s) { is_expected.to eq '-1' }
end
end

end
Loading