Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -5,7 +5,8 @@ set(RUBY_WRAPPER_SRC
ruby_rational.c
ruby_constant.c
ruby_function.c
symengine_macros.c
ruby_ntheory.c
symengine_utils.c
symengine.c
)

Expand Down
2 changes: 1 addition & 1 deletion ext/symengine/ruby_basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <ruby.h>
#include <symengine/cwrapper.h>

#include "symengine_macros.h"
#include "symengine_utils.h"

void cbasic_free(void *ptr);

Expand Down
3 changes: 1 addition & 2 deletions ext/symengine/ruby_constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
#include <ruby.h>
#include <symengine/cwrapper.h>

#include "ruby_basic.h"
#include "symengine.h"
#include "symengine_macros.h"
#include "symengine_utils.h"

VALUE cconstant_const(void (*cwfunc_ptr)(basic_struct*));

Expand Down
19 changes: 1 addition & 18 deletions ext/symengine/ruby_function.c
Original file line number Diff line number Diff line change
@@ -1,25 +1,8 @@
#include "ruby_function.h"


VALUE cfunction_onearg(void (*cwfunc_ptr)(basic_struct*, const basic_struct*), VALUE operand1) {
basic_struct *cresult;
VALUE result;

basic cbasic_operand1;
basic_new_stack(cbasic_operand1);
sympify(operand1, cbasic_operand1);

cresult = basic_new_heap();
cwfunc_ptr(cresult, cbasic_operand1);
result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);
basic_free_stack(cbasic_operand1);

return result;
}

#define IMPLEMENT_ONE_ARG_FUNC(func) \
VALUE cfunction_ ## func(VALUE self, VALUE operand1) { \
return cfunction_onearg(basic_ ## func, operand1); \
return function_onearg(basic_ ## func, operand1); \
}

IMPLEMENT_ONE_ARG_FUNC(abs);
Expand Down
5 changes: 1 addition & 4 deletions ext/symengine/ruby_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
#include <ruby.h>
#include <symengine/cwrapper.h>

#include "ruby_basic.h"
#include "symengine.h"
#include "symengine_macros.h"

VALUE cfunction_func(void (*cwfunc_ptr)(basic_struct*, const basic_struct*), VALUE operand1);
#include "symengine_utils.h"

VALUE cfunction_abs(VALUE self, VALUE operand1);
VALUE cfunction_sin(VALUE self, VALUE operand1);
Expand Down
1 change: 1 addition & 0 deletions ext/symengine/ruby_integer.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ VALUE cinteger_init(VALUE self, VALUE num_value) {
GET_SYMINTFROMVAL(num_value, this);
return self;
}

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

VALUE cntheory_nextprime(VALUE self, VALUE operand1) {
return function_onearg(ntheory_nextprime, operand1);
}

VALUE cntheory_gcd(VALUE self, VALUE operand1, VALUE operand2) {
return function_twoarg(ntheory_gcd, operand1, operand2);
}

VALUE cntheory_lcm(VALUE self, VALUE operand1, VALUE operand2) {
return function_twoarg(ntheory_lcm, operand1, operand2);
}

VALUE cntheory_mod(VALUE self, VALUE operand2) {
VALUE ans = function_twoarg(ntheory_mod, self, operand2);
VALUE ans1 = cbasic_add(ans, operand2);
return function_twoarg(ntheory_mod, ans1, operand2);
}

VALUE cntheory_quotient(VALUE self, VALUE operand1, VALUE operand2) {
return function_twoarg(ntheory_quotient, operand1, operand2);
}

VALUE cntheory_fibonacci(VALUE self, VALUE operand1){
basic_struct *cresult;
VALUE result;

unsigned long cbasic_operand1;
cbasic_operand1 = NUM2ULONG(operand1);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@abinashmeher999 am I using this correctly? Pls check.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, that is correct. If you get unsure about return types, refer here: http://rxr.whitequark.org/mri/ident

Copy link
Member

Choose a reason for hiding this comment

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

Then all you need to do is to add an implicit conversion of SymEngine::Integer into Integer

Copy link
Contributor Author

@rajithv rajithv May 13, 2016

Choose a reason for hiding this comment

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

I figured our half way on how to do this:

so I added a new method to the 'Integer' class
rb_define_method(c_integer, "to_int", cinteger_to_int, 0);

From which I should return a VALUE pointer pointing to a Ruby Bignum or a Fixnum. This can be done by converting a C int by using INT2NUM macro.

The step I'm stuck at is on extracting a C int from the SymEngine Integer object. @abinashmeher999 can you point me to somewhere I can read more about the Ruby Wrapper's SymEngine Integer's structure?

Copy link
Contributor

Choose a reason for hiding this comment

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

@rajithv, the Integer object uses GMP underneath. So you can extract a gmp int easily using the as_mpz() method. If you want an integer, you can call as_int(), but it will raise an exception if the integer doesn't fit into signed long int.

Copy link
Member

Choose a reason for hiding this comment

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

You can convert a SymEngine::Integer to a Ruby string first and then call to_i method

Copy link
Contributor

Choose a reason for hiding this comment

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

+1. This can be done. So instead of using the Ruby C API for the above, you can define #to_int in ruby itself here. Make a new file integer.rb and then proceed.


cresult = basic_new_heap();
ntheory_fibonacci(cresult, cbasic_operand1);
result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);

return result;
}

VALUE cntheory_lucas(VALUE self, VALUE operand1){
basic_struct *cresult;
VALUE result;

unsigned long cbasic_operand1;
cbasic_operand1 = NUM2ULONG(operand1);
Copy link
Member

Choose a reason for hiding this comment

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

What happens when operand1 is a SymEngine integer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

now, it gives an error TypeError: no implicit conversion of SymEngine::Integer into Integer

Can I use sympify for this as well? In C++, the method signature is SymEngine::lucas(unsigned long n). So the cwrapper also expects a unsinged long.


cresult = basic_new_heap();
ntheory_lucas(cresult, cbasic_operand1);
result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);

return result;
}

VALUE cntheory_binomial(VALUE self, VALUE operand1, VALUE operand2){
basic_struct *cresult;
VALUE result;

basic cbasic_operand1;
basic_new_stack(cbasic_operand1);
sympify(operand1, cbasic_operand1);

unsigned long cbasic_operand2;
cbasic_operand2 = NUM2ULONG(operand2);

cresult = basic_new_heap();
ntheory_binomial(cresult, cbasic_operand1, cbasic_operand2);
result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);
basic_free_stack(cbasic_operand1);

return result;
}
20 changes: 20 additions & 0 deletions ext/symengine/ruby_ntheory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef RUBY_NTHEORY_H_
#define RUBY_NTHEORY_H_

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

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

VALUE cntheory_gcd(VALUE self, VALUE operand1, VALUE operand2);
VALUE cntheory_lcm(VALUE self, VALUE operand1, VALUE operand2);
VALUE cntheory_nextprime(VALUE self, VALUE operand1);
VALUE cntheory_mod(VALUE self, VALUE operand2);
VALUE cntheory_quotient(VALUE self, VALUE operand1, VALUE operand2);
VALUE cntheory_fibonacci(VALUE self, VALUE operand1);
VALUE cntheory_lucas(VALUE self, VALUE operand1);
VALUE cntheory_binomial(VALUE self, VALUE operand1, VALUE operand2);

#endif //RUBY_NTHEORY_H_
11 changes: 11 additions & 0 deletions ext/symengine/symengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "ruby_rational.h"
#include "ruby_constant.h"
#include "ruby_function.h"
#include "ruby_ntheory.h"
#include "symengine.h"

///////////////////
Expand Down Expand Up @@ -52,6 +53,7 @@ void Init_symengine() {
c_integer = rb_define_class_under(m_symengine, "Integer", c_basic);
rb_define_alloc_func(c_integer, cbasic_alloc);
rb_define_method(c_integer, "initialize", cinteger_init, 1);
rb_define_method(c_integer, "%", cntheory_mod, 1);

//Rational class
c_rational = rb_define_class_under(m_symengine, "Rational", c_basic);
Expand Down Expand Up @@ -145,4 +147,13 @@ void Init_symengine() {
rb_define_module_function(m_symengine, "zeta", cfunction_zeta, 1);
rb_define_module_function(m_symengine, "gamma", cfunction_gamma, 1);

//NTheory Functions as Module Level Functions
rb_define_module_function(m_symengine, "gcd", cntheory_gcd, 2);
rb_define_module_function(m_symengine, "lcm", cntheory_lcm, 2);
rb_define_module_function(m_symengine, "nextprime", cntheory_nextprime, 1);
rb_define_module_function(m_symengine, "quotient", cntheory_quotient, 2);
rb_define_module_function(m_symengine, "fibonacci", cntheory_fibonacci, 1);
rb_define_module_function(m_symengine, "lucas", cntheory_lucas, 1);
rb_define_module_function(m_symengine, "binomial", cntheory_binomial, 2);

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "symengine_macros.h"
#include "symengine_utils.h"
#include "symengine.h"

void sympify(VALUE operand2, basic_struct *cbasic_operand2) {
Expand Down Expand Up @@ -111,3 +111,41 @@ VALUE Klass_of_Basic(const basic_struct *basic_ptr) {
return c_basic;
}
}

VALUE function_onearg(void (*cwfunc_ptr)(basic_struct*, const basic_struct*), VALUE operand1) {
basic_struct *cresult;
VALUE result;

basic cbasic_operand1;
basic_new_stack(cbasic_operand1);
sympify(operand1, cbasic_operand1);

cresult = basic_new_heap();
cwfunc_ptr(cresult, cbasic_operand1);
result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);
basic_free_stack(cbasic_operand1);

return result;
}

VALUE function_twoarg(void (*cwfunc_ptr)(basic_struct*, const basic_struct*, const basic_struct*),
VALUE operand1, VALUE operand2) {
basic_struct *cresult;
VALUE result;

basic cbasic_operand1;
basic_new_stack(cbasic_operand1);
sympify(operand1, cbasic_operand1);

basic cbasic_operand2;
basic_new_stack(cbasic_operand2);
sympify(operand2, cbasic_operand2);

cresult = basic_new_heap();
cwfunc_ptr(cresult, cbasic_operand1, cbasic_operand2);
result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);
basic_free_stack(cbasic_operand1);
basic_free_stack(cbasic_operand2);

return result;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
#define SYMENGINE_MACROS_H_

#include "ruby.h"
#include "ruby_basic.h"
#include "symengine/cwrapper.h"

//Returns the pointer wrapped inside the Ruby VALUE
void sympify(VALUE operand2, basic_struct *cbasic_operand2);
//Returns the Ruby class of the corresponding basic_struct pointer
VALUE Klass_of_Basic(const basic_struct *basic_ptr);
//Returns the result from the function pointed by cwfunc_ptr: for one argument functions
VALUE function_onearg(void (*cwfunc_ptr)(basic_struct*, const basic_struct*), VALUE operand1);
//Returns the result from the function pointed by cwfunc_ptr: for two argument functions
VALUE function_twoarg(void (*cwfunc_ptr)(basic_struct*, const basic_struct*, const basic_struct*),
VALUE operand1, VALUE operand2);

//Obtains the value from Ruby Fixnum or Bignum to an already allocated basic_struct
#define GET_SYMINTFROMVAL(num_value, this) { \
Expand Down
1 change: 1 addition & 0 deletions lib/symengine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ def symbols ary_or_string, *params
require 'symengine/symengine'
require 'symengine/iruby'
require 'symengine/basic'
require 'symengine/integer'
7 changes: 7 additions & 0 deletions lib/symengine/integer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module SymEngine
class Integer
def to_int
self.to_s.to_i
end
end
end
Loading