symengine 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +1 -76
  5. data/README.md +29 -11
  6. data/cmake/FindRuby.cmake +286 -0
  7. data/ext/symengine/CMakeLists.txt +26 -0
  8. data/ext/symengine/extconf.rb +15 -0
  9. data/ext/symengine/ruby_basic.c +254 -0
  10. data/ext/symengine/ruby_basic.h +53 -0
  11. data/ext/symengine/ruby_integer.c +8 -0
  12. data/ext/symengine/ruby_integer.h +8 -0
  13. data/ext/symengine/ruby_rational.c +23 -0
  14. data/ext/symengine/ruby_rational.h +8 -0
  15. data/ext/symengine/ruby_symbol.c +13 -0
  16. data/ext/symengine/ruby_symbol.h +8 -0
  17. data/ext/symengine/symengine.c +49 -0
  18. data/ext/symengine/symengine.h +15 -0
  19. data/ext/symengine/symengine_macros.c +49 -0
  20. data/ext/symengine/symengine_macros.h +21 -0
  21. data/spec/arit_spec.rb +146 -0
  22. data/spec/basic_spec.rb +217 -0
  23. data/spec/integer_spec.rb +56 -0
  24. data/spec/rational_spec.rb +51 -0
  25. data/spec/spec_helper.rb +96 -0
  26. data/spec/symbol_spec.rb +20 -0
  27. data/symengine.gemspec +19 -0
  28. metadata +29 -26
  29. data/lib/symengine/CMakeFiles/CMakeDirectoryInformation.cmake +0 -16
  30. data/lib/symengine/CMakeFiles/progress.marks +0 -1
  31. data/lib/symengine/CMakeFiles/symengine_ruby.dir/C.includecache +0 -138
  32. data/lib/symengine/CMakeFiles/symengine_ruby.dir/DependInfo.cmake +0 -33
  33. data/lib/symengine/CMakeFiles/symengine_ruby.dir/__/__/ext/symengine/ruby_basic.c.o +0 -0
  34. data/lib/symengine/CMakeFiles/symengine_ruby.dir/__/__/ext/symengine/ruby_integer.c.o +0 -0
  35. data/lib/symengine/CMakeFiles/symengine_ruby.dir/__/__/ext/symengine/ruby_rational.c.o +0 -0
  36. data/lib/symengine/CMakeFiles/symengine_ruby.dir/__/__/ext/symengine/ruby_symbol.c.o +0 -0
  37. data/lib/symengine/CMakeFiles/symengine_ruby.dir/__/__/ext/symengine/symengine.c.o +0 -0
  38. data/lib/symengine/CMakeFiles/symengine_ruby.dir/__/__/ext/symengine/symengine_macros.c.o +0 -0
  39. data/lib/symengine/CMakeFiles/symengine_ruby.dir/build.make +0 -241
  40. data/lib/symengine/CMakeFiles/symengine_ruby.dir/cmake_clean.cmake +0 -15
  41. data/lib/symengine/CMakeFiles/symengine_ruby.dir/depend.internal +0 -94
  42. data/lib/symengine/CMakeFiles/symengine_ruby.dir/depend.make +0 -94
  43. data/lib/symengine/CMakeFiles/symengine_ruby.dir/flags.make +0 -8
  44. data/lib/symengine/CMakeFiles/symengine_ruby.dir/link.txt +0 -1
  45. data/lib/symengine/CMakeFiles/symengine_ruby.dir/progress.make +0 -7
  46. data/lib/symengine/CTestTestfile.cmake +0 -6
  47. data/lib/symengine/Makefile +0 -347
  48. data/lib/symengine/cmake_install.cmake +0 -34
  49. data/lib/symengine/symengine.so +0 -0
@@ -0,0 +1,26 @@
1
+ set(RUBY_WRAPPER_SRC
2
+ ruby_basic.c
3
+ ruby_symbol.c
4
+ ruby_integer.c
5
+ ruby_rational.c
6
+ symengine_macros.c
7
+ symengine.c
8
+ )
9
+
10
+ include_directories(BEFORE ${RUBY_INCLUDE_DIRS})
11
+
12
+ add_library(symengine_ruby SHARED ${RUBY_WRAPPER_SRC})
13
+ target_link_libraries(symengine_ruby ${SYMENGINE_LIBRARIES} ${RUBY_LIBRARY})
14
+ set_target_properties(symengine_ruby PROPERTIES
15
+ PREFIX ""
16
+ SUFFIX ".so"
17
+ OUTPUT_NAME "symengine"
18
+ LIBRARY_OUTPUT_DIRECTORY "${ruby_wrapper_BINARY_DIR}/lib/symengine"
19
+ )
20
+
21
+ # Ruby gems require a install target.
22
+ install(TARGETS symengine_ruby
23
+ RUNTIME DESTINATION lib/symengine
24
+ ARCHIVE DESTINATION lib/symengine
25
+ LIBRARY DESTINATION lib/symengine
26
+ )
@@ -0,0 +1,15 @@
1
+ require 'rbconfig'
2
+
3
+ ruby_executable = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['RUBY_INSTALL_NAME'] + RbConfig::CONFIG['EXEEXT'])
4
+
5
+ generator = ""
6
+
7
+ if (RbConfig::CONFIG['host_os'] =~ /mingw/)
8
+ generator = '-G "MSYS Makefiles"'
9
+ elsif (RbConfig::CONFIG['host_os'] =~ /cygwin/)
10
+ generator = '-G "Unix Makefiles"'
11
+ elsif (RbConfig::CONFIG['host_os'] =~ /mswin/)
12
+ generator = '-G "NMake Makefiles"'
13
+ end
14
+
15
+ exec 'cmake %s -DCMAKE_INSTALL_PREFIX=../../ -DRUBY_EXECUTABLE=%s %s ../../ ' % [generator, ruby_executable, ARGV.join(" ")]
@@ -0,0 +1,254 @@
1
+ #include "ruby_basic.h"
2
+
3
+ void cbasic_free(void *ptr){
4
+ basic_struct *basic_ptr = ptr;
5
+ basic_free_stack(basic_ptr);
6
+ }
7
+
8
+ void cbasic_free_heap(void *ptr) {
9
+ basic_struct *basic_ptr = ptr;
10
+ basic_free_heap(basic_ptr);
11
+ }
12
+
13
+ VALUE cbasic_alloc(VALUE klass){
14
+ basic_struct *struct_ptr = basic_new_heap();
15
+ return Data_Wrap_Struct(klass, NULL, cbasic_free_heap, struct_ptr);
16
+ }
17
+
18
+ VALUE cbasic_binary_op(VALUE self, VALUE operand2, void (*cwfunc_ptr)(basic_struct*, const basic_struct*, const basic_struct*)){
19
+ basic_struct *this, *cresult;
20
+ VALUE result;
21
+
22
+ basic cbasic_operand2;
23
+ basic_new_stack(cbasic_operand2);
24
+
25
+ Data_Get_Struct(self, basic_struct, this);
26
+ sympify(operand2, cbasic_operand2);
27
+
28
+ cresult = basic_new_heap();
29
+ cwfunc_ptr(cresult, this, cbasic_operand2);
30
+ result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);
31
+ basic_free_stack(cbasic_operand2);
32
+
33
+ return result;
34
+ }
35
+
36
+ VALUE cbasic_unary_op(VALUE self, void (*cwfunc_ptr)(basic_struct*, const basic_struct*)){
37
+ basic_struct *this, *cresult;
38
+ VALUE result;
39
+
40
+ Data_Get_Struct(self, basic_struct, this);
41
+
42
+ cresult = basic_new_heap();
43
+ cwfunc_ptr(cresult, this);
44
+ result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);
45
+
46
+ return result;
47
+ }
48
+
49
+ VALUE cbasic_add(VALUE self, VALUE operand2){
50
+ return cbasic_binary_op(self, operand2, basic_add);
51
+ }
52
+
53
+ VALUE cbasic_sub(VALUE self, VALUE operand2){
54
+ return cbasic_binary_op(self, operand2, basic_sub);
55
+ }
56
+
57
+ VALUE cbasic_mul(VALUE self, VALUE operand2){
58
+ return cbasic_binary_op(self, operand2, basic_mul);
59
+ }
60
+
61
+ VALUE cbasic_div(VALUE self, VALUE operand2){
62
+ return cbasic_binary_op(self, operand2, basic_div);
63
+ }
64
+
65
+ VALUE cbasic_pow(VALUE self, VALUE operand2){
66
+ return cbasic_binary_op(self, operand2, basic_pow);
67
+ }
68
+
69
+ VALUE cbasic_diff(VALUE self, VALUE operand2) {
70
+ basic_struct *this, *cresult;
71
+ VALUE result;
72
+
73
+ basic cbasic_operand2;
74
+ basic_new_stack(cbasic_operand2);
75
+
76
+ Data_Get_Struct(self, basic_struct, this);
77
+ sympify(operand2, cbasic_operand2);
78
+
79
+ cresult = basic_new_heap();
80
+ int status = basic_diff(cresult, this, cbasic_operand2);
81
+ if (status == 0) {
82
+ basic_free_stack(cbasic_operand2);
83
+ basic_free_heap(cresult);
84
+ return Qnil;
85
+ }
86
+ result = Data_Wrap_Struct(Klass_of_Basic(cresult), NULL , cbasic_free_heap, cresult);
87
+ basic_free_stack(cbasic_operand2);
88
+
89
+ return result;
90
+ }
91
+
92
+ VALUE cbasic_eq(VALUE self, VALUE operand2) {
93
+ basic_struct *this;
94
+
95
+ basic cbasic_operand2;
96
+ basic_new_stack(cbasic_operand2);
97
+ Data_Get_Struct(self, basic_struct, this);
98
+ sympify(operand2, cbasic_operand2);
99
+
100
+ VALUE ret_val = basic_eq(this, cbasic_operand2) ? Qtrue : Qfalse;
101
+ basic_free_stack(cbasic_operand2);
102
+
103
+ return ret_val;
104
+ }
105
+
106
+ VALUE cbasic_neq(VALUE self, VALUE operand2) {
107
+ basic_struct *this;
108
+
109
+ basic cbasic_operand2;
110
+ basic_new_stack(cbasic_operand2);
111
+ Data_Get_Struct(self, basic_struct, this);
112
+ sympify(operand2, cbasic_operand2);
113
+
114
+ VALUE ret_val = basic_neq(this, cbasic_operand2) ? Qtrue : Qfalse;
115
+ basic_free_stack(cbasic_operand2);
116
+
117
+ return ret_val;
118
+ }
119
+
120
+ VALUE cbasic_neg(VALUE self){
121
+ return cbasic_unary_op(self, basic_neg);
122
+ }
123
+
124
+ VALUE cbasic_get_args(VALUE self) {
125
+ basic_struct *this, *iterator_basic;
126
+ CVecBasic *args = vecbasic_new();
127
+ int size = 0;
128
+
129
+ Data_Get_Struct(self, basic_struct, this);
130
+ basic_get_args(this, args);
131
+
132
+ size = vecbasic_size(args);
133
+ VALUE ruby_array = rb_ary_new2(size);
134
+ int i = 0;
135
+ VALUE temp = NULL;
136
+ for(i = 0; i < size; i++) {
137
+ basic_struct *temp_basic = basic_new_heap();
138
+ vecbasic_get(args, i, temp_basic);
139
+ temp = Data_Wrap_Struct(rb_obj_class(self), NULL , cbasic_free_heap, temp_basic);
140
+ rb_ary_push(ruby_array, temp);
141
+ }
142
+ vecbasic_free(args);
143
+ return ruby_array;
144
+ }
145
+
146
+ VALUE cbasic_free_symbols(VALUE self) {
147
+ basic_struct *this, *iterator_basic;
148
+ CSetBasic *symbols = setbasic_new();
149
+ int size = 0;
150
+
151
+ Data_Get_Struct(self, basic_struct, this);
152
+ basic_free_symbols(this, symbols);
153
+
154
+ size = setbasic_size(symbols);
155
+ VALUE ruby_array = rb_ary_new2(size);
156
+ int i = 0;
157
+ VALUE temp = NULL;
158
+ for(i = 0; i < size; i++) {
159
+ basic_struct *temp_basic = basic_new_heap();
160
+ setbasic_get(symbols, i, temp_basic);
161
+ temp = Data_Wrap_Struct(rb_obj_class(self), NULL , cbasic_free_heap, temp_basic);
162
+ rb_ary_push(ruby_array, temp);
163
+ }
164
+ setbasic_free(symbols);
165
+ return ruby_array;
166
+ }
167
+
168
+ VALUE cbasic_to_str(VALUE self){
169
+ basic_struct *this;
170
+ char *str_ptr;
171
+ VALUE result;
172
+
173
+ Data_Get_Struct(self, basic_struct, this);
174
+
175
+ str_ptr = basic_str(this);
176
+ result = rb_str_new_cstr(str_ptr);
177
+ basic_str_free(str_ptr);
178
+
179
+ return result;
180
+ }
181
+
182
+ VALUE cbasic_expand(VALUE self){
183
+ return cbasic_unary_op(self, basic_expand);
184
+ }
185
+
186
+ VALUE cbasic_hash(VALUE self){
187
+ basic_struct *this;
188
+ Data_Get_Struct(self, basic_struct, this);
189
+ // All ruby objects return FIXNUM when `hash` method is called.
190
+ // Though this function returns BIGNUM it won't be a problem, since
191
+ // we need proper comparison only among objects in SymEngine.
192
+ // The objects that should have the same hash will always match
193
+ // and when comparing to the FIXNUM from hash of other ruby objects,
194
+ // it will return false as it is supposed to.
195
+ // However, an alternate implementation is given below
196
+ // long lhash = basic_hash(this) % FIX2LONG(FIXNUM_MAX);
197
+ // return LONG2FIX(lhash);
198
+ return SIZET2NUM(basic_hash(this));
199
+ }
200
+
201
+ int insert_entries(VALUE key, VALUE val, VALUE input) {
202
+ CMapBasicBasic *cmapbb;
203
+ Data_Get_Struct(input, CMapBasicBasic, cmapbb);
204
+
205
+ basic ckey, cval;
206
+ basic_new_stack(ckey);
207
+ basic_new_stack(cval);
208
+ sympify(key, ckey);
209
+ sympify(val, cval);
210
+
211
+ mapbasicbasic_insert(cmapbb, ckey, cval);
212
+
213
+ basic_free_stack(ckey);
214
+ basic_free_stack(cval);
215
+ }
216
+
217
+ VALUE cbasic_subs(int argc, VALUE *argv, VALUE self) {
218
+ basic_struct *this, *cresult;
219
+ cresult = basic_new_heap();
220
+
221
+ VALUE val_a, val_b;
222
+ Data_Get_Struct(self, basic_struct, this);
223
+
224
+ rb_scan_args(argc, argv, "11", &val_a, &val_b); // 1 mandatory and 1 optional parameter
225
+ if (argc == 1) {
226
+ Check_Type(val_a, T_HASH);
227
+ CMapBasicBasic *cmapbb = mapbasicbasic_new();
228
+ VALUE mapbb = Data_Wrap_Struct(rb_cObject, NULL, mapbasicbasic_free, cmapbb);
229
+
230
+ rb_hash_foreach(val_a, insert_entries, mapbb);
231
+ basic_subs(cresult, this, cmapbb);
232
+ } else {
233
+ basic a, b;
234
+ basic_new_stack(a);
235
+ basic_new_stack(b);
236
+
237
+ sympify(val_a, a);
238
+ sympify(val_b, b);
239
+ basic_subs2(cresult, this, a, b);
240
+
241
+ basic_free_stack(a);
242
+ basic_free_stack(b);
243
+ }
244
+
245
+ return Data_Wrap_Struct(Klass_of_Basic(cresult), NULL, cbasic_free_heap, cresult);
246
+ }
247
+
248
+ VALUE cbasic_coerce(VALUE self, VALUE other){
249
+ basic_struct *cbasic_operand2;
250
+ cbasic_operand2 = basic_new_heap();
251
+ sympify(other, cbasic_operand2);
252
+ VALUE new_other = Data_Wrap_Struct(Klass_of_Basic(cbasic_operand2), NULL , cbasic_free_heap, cbasic_operand2);
253
+ return rb_assoc_new(new_other, self);
254
+ }
@@ -0,0 +1,53 @@
1
+ #ifndef RUBY_BASIC_H_
2
+ #define RUBY_BASIC_H_
3
+
4
+ #include <ruby.h>
5
+ #include <symengine/cwrapper.h>
6
+
7
+ #include "symengine_macros.h"
8
+
9
+ void cbasic_free(void *ptr);
10
+
11
+ void cbasic_free_heap(void *ptr);
12
+
13
+ VALUE cbasic_alloc(VALUE klass);
14
+
15
+ VALUE cbasic_binary_op(VALUE self, VALUE operand2, void (*cwfunc_ptr)(basic_struct*, const basic_struct*, const basic_struct*));
16
+
17
+ VALUE cbasic_unary_op(VALUE self, void (*cwfunc_ptr)(basic_struct*, const basic_struct*));
18
+
19
+ VALUE cbasic_add(VALUE self, VALUE operand2);
20
+
21
+ VALUE cbasic_sub(VALUE self, VALUE operand2);
22
+
23
+ VALUE cbasic_mul(VALUE self, VALUE operand2);
24
+
25
+ VALUE cbasic_div(VALUE self, VALUE operand2);
26
+
27
+ VALUE cbasic_pow(VALUE self, VALUE operand2);
28
+
29
+ VALUE cbasic_diff(VALUE self, VALUE operand2);
30
+
31
+ VALUE cbasic_eq(VALUE self, VALUE operand2);
32
+
33
+ VALUE cbasic_neq(VALUE self, VALUE operand2);
34
+
35
+ VALUE cbasic_neg(VALUE self);
36
+
37
+ VALUE cbasic_get_args(VALUE self);
38
+
39
+ VALUE cbasic_free_symbols(VALUE self);
40
+
41
+ VALUE cbasic_to_str(VALUE self);
42
+
43
+ VALUE cbasic_expand(VALUE self);
44
+
45
+ VALUE cbasic_hash(VALUE self);
46
+
47
+ int insert_entries(VALUE key, VALUE val, VALUE val_map_basic_basic);
48
+
49
+ VALUE cbasic_subs(int argc, VALUE *argv, VALUE self);
50
+
51
+ VALUE cbasic_coerce(VALUE self, VALUE other);
52
+
53
+ #endif //RUBY_BASIC_H_
@@ -0,0 +1,8 @@
1
+ #include "ruby_integer.h"
2
+
3
+ VALUE cinteger_init(VALUE self, VALUE num_value) {
4
+ basic_struct *this;
5
+ Data_Get_Struct(self, basic_struct, this);
6
+ GET_SYMINTFROMVAL(num_value, this);
7
+ return self;
8
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_INTEGER_H_
2
+ #define RUBY_INTEGER_H_
3
+
4
+ #include "ruby_basic.h"
5
+
6
+ VALUE cinteger_init(VALUE self, VALUE num_value);
7
+
8
+ #endif //RUBY_INTEGER_H_
@@ -0,0 +1,23 @@
1
+ #include "ruby_rational.h"
2
+
3
+ VALUE crational_init(VALUE self, VALUE rat_value) {
4
+ basic_struct *this;
5
+ basic num_basic, den_basic;
6
+
7
+ basic_new_stack(num_basic);
8
+ basic_new_stack(den_basic);
9
+
10
+ Data_Get_Struct(self, basic_struct, this);
11
+
12
+ VALUE num, den;
13
+ num = rb_funcall(rat_value, rb_intern("numerator"), 0, NULL);
14
+ den = rb_funcall(rat_value, rb_intern("denominator"), 0, NULL);
15
+
16
+ GET_SYMINTFROMVAL(num, num_basic);
17
+ GET_SYMINTFROMVAL(den, den_basic);
18
+
19
+ rational_set(this, num_basic, den_basic);
20
+ basic_free_stack(num_basic);
21
+ basic_free_stack(den_basic);
22
+ return self;
23
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_RATIONAL_H_
2
+ #define RUBY_RATIONAL_H_
3
+
4
+ #include "ruby_basic.h"
5
+
6
+ VALUE crational_init(VALUE self, VALUE rat_value);
7
+
8
+ #endif //RUBY_RATIONAL_H_
@@ -0,0 +1,13 @@
1
+ #include "ruby_symbol.h"
2
+
3
+ VALUE csymbol_init(VALUE self, VALUE name) {
4
+ Check_Type(name, T_STRING);
5
+ basic_struct *this;
6
+ char *str_ptr = StringValueCStr(name);
7
+
8
+ Data_Get_Struct(self, basic_struct, this);
9
+
10
+ symbol_set(this, str_ptr);
11
+
12
+ return self;
13
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_SYMBOL_H_
2
+ #define RUBY_SYMBOL_H_
3
+
4
+ #include "ruby_basic.h"
5
+
6
+ VALUE csymbol_init(VALUE self, VALUE name);
7
+
8
+ #endif //RUBY_SYMBOL_H_
@@ -0,0 +1,49 @@
1
+ #include "ruby_basic.h"
2
+ #include "ruby_symbol.h"
3
+ #include "ruby_integer.h"
4
+ #include "ruby_rational.h"
5
+ #include "symengine.h"
6
+
7
+ ///////////////////
8
+ // Ruby Bindings //
9
+ ///////////////////
10
+
11
+ void Init_symengine() {
12
+ m_symengine = rb_define_module("SymEngine");
13
+
14
+ //Basic class
15
+ c_basic = rb_define_class_under(m_symengine, "Basic", rb_cObject);
16
+ rb_define_alloc_func(c_basic, cbasic_alloc);
17
+ rb_define_method(c_basic, "+", cbasic_add, 1);
18
+ rb_define_method(c_basic, "-", cbasic_sub, 1);
19
+ rb_define_method(c_basic, "*", cbasic_mul, 1);
20
+ rb_define_method(c_basic, "/", cbasic_div, 1);
21
+ rb_define_method(c_basic, "**", cbasic_pow, 1);
22
+ rb_define_method(c_basic, "diff", cbasic_diff, 1);
23
+ rb_define_method(c_basic, "==", cbasic_eq, 1);
24
+ rb_define_method(c_basic, "eql?", cbasic_eq, 1);
25
+ rb_define_method(c_basic, "!=", cbasic_neq, 1);
26
+ rb_define_method(c_basic, "-@", cbasic_neg, 0);
27
+ rb_define_method(c_basic, "to_s", cbasic_to_str, 0);
28
+ rb_define_method(c_basic, "expand", cbasic_expand, 0);
29
+ rb_define_method(c_basic, "args", cbasic_get_args, 0);
30
+ rb_define_protected_method(c_basic, "pr_free_symbols", cbasic_free_symbols, 0);
31
+ rb_define_method(c_basic, "hash", cbasic_hash, 0);
32
+ rb_define_method(c_basic, "subs", cbasic_subs, -1);
33
+ rb_define_method(c_basic, "coerce", cbasic_coerce, 1);
34
+
35
+ //Symbol class
36
+ c_symbol = rb_define_class_under(m_symengine, "Symbol", c_basic);
37
+ rb_define_alloc_func(c_symbol, cbasic_alloc);
38
+ rb_define_method(c_symbol, "initialize", csymbol_init, 1);
39
+
40
+ //Integer class
41
+ c_integer = rb_define_class_under(m_symengine, "Integer", c_basic);
42
+ rb_define_alloc_func(c_integer, cbasic_alloc);
43
+ rb_define_method(c_integer, "initialize", cinteger_init, 1);
44
+
45
+ //Rational class
46
+ c_rational = rb_define_class_under(m_symengine, "Rational", c_basic);
47
+ rb_define_alloc_func(c_rational, cbasic_alloc);
48
+ rb_define_method(c_rational, "initialize", crational_init, 1);
49
+ }