symengine 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,15 @@
1
+ #ifndef SYMENGINE_H_
2
+ #define SYMENGINE_H_
3
+
4
+ #include "ruby.h"
5
+
6
+ //variable name for a module starts with m
7
+ VALUE m_symengine;
8
+
9
+ //variable names for classes begin with c
10
+ VALUE c_basic;
11
+ VALUE c_symbol;
12
+ VALUE c_integer;
13
+ VALUE c_rational;
14
+
15
+ #endif //SYMENGINE_H_
@@ -0,0 +1,49 @@
1
+ #include "symengine_macros.h"
2
+ #include "symengine.h"
3
+
4
+ void sympify(VALUE operand2, basic_struct *cbasic_operand2) {
5
+ basic_struct *temp;
6
+ VALUE new_operand2, num, den;
7
+
8
+ switch(TYPE(operand2)) {
9
+ case T_FIXNUM:
10
+ case T_BIGNUM:
11
+ GET_SYMINTFROMVAL(operand2, cbasic_operand2);
12
+ break;
13
+
14
+ case T_RATIONAL:
15
+ num = rb_funcall(operand2, rb_intern("numerator"), 0, NULL);
16
+ den = rb_funcall(operand2, rb_intern("denominator"), 0, NULL);
17
+
18
+ basic num_basic, den_basic;
19
+ basic_new_stack(num_basic);
20
+ basic_new_stack(den_basic);
21
+
22
+ GET_SYMINTFROMVAL(num, num_basic);
23
+ GET_SYMINTFROMVAL(den, den_basic);
24
+
25
+ rational_set(cbasic_operand2, num_basic, den_basic);
26
+
27
+ basic_free_stack(num_basic);
28
+ basic_free_stack(den_basic);
29
+ break;
30
+
31
+ case T_DATA:
32
+ Data_Get_Struct(operand2, basic_struct, temp);
33
+ basic_assign(cbasic_operand2, temp);
34
+ break;
35
+ }
36
+ }
37
+
38
+ VALUE Klass_of_Basic(const basic_struct *basic_ptr) {
39
+ switch(basic_get_type(basic_ptr)) {
40
+ case SYMENGINE_SYMBOL:
41
+ return c_symbol;
42
+ case SYMENGINE_INTEGER:
43
+ return c_integer;
44
+ case SYMENGINE_RATIONAL:
45
+ return c_rational;
46
+ default:
47
+ return c_basic;
48
+ }
49
+ }
@@ -0,0 +1,21 @@
1
+ #ifndef SYMENGINE_MACROS_H_
2
+ #define SYMENGINE_MACROS_H_
3
+
4
+ #include "ruby.h"
5
+ #include "symengine/cwrapper.h"
6
+
7
+ //Returns the pointer wrapped inside the Ruby VALUE
8
+ void sympify(VALUE operand2, basic_struct *cbasic_operand2);
9
+ //Returns the Ruby class of the corresponding basic_struct pointer
10
+ VALUE Klass_of_Basic(const basic_struct *basic_ptr);
11
+
12
+ //Obtains the value from Ruby Fixnum or Bignum to an already allocated basic_struct
13
+ #define GET_SYMINTFROMVAL(num_value, this) { \
14
+ if ( ! RB_TYPE_P(num_value, T_FIXNUM) && ! RB_TYPE_P(num_value, T_BIGNUM) ) { \
15
+ rb_raise(rb_eTypeError, "Invalid Type: Fixnum or Bignum required"); \
16
+ } \
17
+ VALUE Rb_Temp_String = rb_funcall(num_value, rb_intern("to_s"), 0, NULL); \
18
+ integer_set_str(this, StringValueCStr(Rb_Temp_String)); \
19
+ }
20
+
21
+ #endif //SYMENGINE_MACROS_H_
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Arithmetic test cases' do
4
+ before :each do
5
+ end
6
+
7
+ it 'test_arit1' do
8
+ x = SymEngine::Symbol.new('x')
9
+ y = SymEngine::Symbol.new('y')
10
+ e = x + y
11
+ e = x * y
12
+ e = SymEngine::Integer.new(2) * x
13
+ e = 2 * x
14
+ e = x + 1
15
+ e = 1 + x
16
+ end
17
+
18
+ it 'test_arit2' do
19
+ x = SymEngine::Symbol.new('x')
20
+ y = SymEngine::Symbol.new('y')
21
+ assert x + x == SymEngine::Integer.new(2) * x
22
+ assert x + x != SymEngine::Integer.new(3) * x
23
+ assert x + y == y + x
24
+ assert x + x == 2 * x
25
+ assert x + x == x * 2
26
+ assert x + x + x == 3 * x
27
+ assert x + y + x + x == 3 * x + y
28
+
29
+ assert(!(x + x == 3 * x))
30
+ assert(!(x + x != 2 * x))
31
+ end
32
+
33
+ it 'test_arit3' do
34
+ x = SymEngine::Symbol.new('x')
35
+ y = SymEngine::Symbol.new('y')
36
+ expect do
37
+ ('x' * x)
38
+ end.to raise_error(TypeError)
39
+ end
40
+
41
+ it 'test_arit4' do
42
+ x = SymEngine::Symbol.new('x')
43
+ y = SymEngine::Symbol.new('y')
44
+ assert x * x == x**2
45
+ assert x * y == y * x
46
+ assert x * x * x == x**3
47
+ assert x * y * x * x == x**3 * y
48
+ end
49
+
50
+ it 'test_arit5' do
51
+ x = SymEngine::Symbol.new('x')
52
+ y = SymEngine::Symbol.new('y')
53
+ e = (x + y)**2
54
+ f = e.expand
55
+ assert e == (x + y)**2
56
+ assert e != x**2 + 2 * x * y + y**2
57
+ expect(e).to be_an_instance_of SymEngine::Basic
58
+ assert f == x**2 + 2 * x * y + y**2
59
+ expect(f).to be_an_instance_of SymEngine::Basic
60
+ end
61
+
62
+ it 'test_arit6' do
63
+ x = SymEngine::Symbol.new('x')
64
+ y = SymEngine::Symbol.new('y')
65
+ e = x + y
66
+ assert(e.to_s == 'x + y') || 'y + x'
67
+ e = x * y
68
+ assert(e.to_s == 'x*y') || 'y*x'
69
+ e = Integer(2) * x
70
+ assert e.to_s == '2*x'
71
+ e = 2 * x
72
+ assert e.to_s == '2*x'
73
+ end
74
+
75
+ it 'test_arit7' do
76
+ x = SymEngine::Symbol.new('x')
77
+ y = SymEngine::Symbol.new('y')
78
+ assert x - x == 0
79
+ assert x - y != y - x
80
+ assert 2 * x - x == x
81
+ assert 3 * x - x == 2 * x
82
+
83
+ assert 2 * x * y - x * y == x * y
84
+ end
85
+
86
+ it 'test_arit8' do
87
+ x = SymEngine::Symbol.new('x')
88
+ y = SymEngine::Symbol.new('y')
89
+ z = SymEngine::Symbol.new('z')
90
+ assert x**y * x**x == x**(x + y)
91
+ assert x**y * x**x * x**z == x**(x + y + z)
92
+ assert x**y - x**y == 0
93
+
94
+ assert x**2 / x == x
95
+ assert y * x**2 / (x * y) == x
96
+ assert (2 * x**3 * y**2 * z)**3 / 8 == x**9 * y**6 * z**3
97
+ assert (2 * y**(-2 * x**2)) * (3 * y**(2 * x**2)) == 6
98
+ end
99
+
100
+ it 'test_expand1' do
101
+ x = SymEngine::Symbol.new('x')
102
+ y = SymEngine::Symbol.new('y')
103
+ z = SymEngine::Symbol.new('z')
104
+ assert ((2 * x + y)**2).expand == 4 * x**2 + 4 * x * y + y**2
105
+ assert (x**2)**3 == x**6
106
+ assert ((2 * x**2 + 3 * y)**2).expand == 4 * x**4 + 12 * x**2 * y + 9 * y**2
107
+ assert ((2 * x / 3 + y / 4)**2).expand == 4 * x**2 / 9 + x * y / 3 + y**2 / 16
108
+ end
109
+
110
+ it 'test_arit9' do
111
+ x = SymEngine::Symbol.new('x')
112
+ y = SymEngine::Symbol.new('y')
113
+ assert 1 / x == 1 / x
114
+ assert 1 / x != 1 / y
115
+ end
116
+
117
+ it 'test_expand2' do
118
+ y = SymEngine::Symbol.new('y')
119
+ z = SymEngine::Symbol.new('z')
120
+ assert ((1 / (y * z) - y * z) * y * z).expand == 1 - (y * z)**2
121
+ end
122
+
123
+ it 'test_expand3' do
124
+ x = SymEngine::Symbol.new('x')
125
+ y = SymEngine::Symbol.new('y')
126
+ assert ((1 / (x * y) - x * y + 2) * (1 + x * y)).expand == 3 + 1 / (x * y) + x * y - (x * y)**2
127
+ end
128
+
129
+ it 'test_args' do
130
+ x = SymEngine::Symbol.new('x')
131
+ y = SymEngine::Symbol.new('y')
132
+ assert (x**2).args == [x, 2]
133
+ assert (x**2 + 5).args == [5, x**2]
134
+ assert (x**2 + 2 * x * y + 5).args == [5, 2 * x * y, x**2]
135
+ assert (2 * x**2).args == [2, x**2]
136
+ assert (2 * x**2 * y).args == [2, x**2, y]
137
+ end
138
+
139
+ it 'test_free_Symbols' do
140
+ x = SymEngine::Symbol.new('x')
141
+ y = SymEngine::Symbol.new('y')
142
+ z = SymEngine::Symbol.new('z')
143
+ assert (x**2).free_symbols == Set.new([x])
144
+ assert (x**y + z).free_symbols == Set.new([x, y, z])
145
+ end
146
+ end
@@ -0,0 +1,217 @@
1
+ require 'spec_helper'
2
+
3
+ describe SymEngine do
4
+ before :each do
5
+ end
6
+
7
+ describe SymEngine::Basic do
8
+ before :each do
9
+ end
10
+
11
+ describe '.new' do
12
+ context 'with no arguments' do
13
+ it 'returns a Basic object' do
14
+ basic = SymEngine::Basic.new
15
+ expect(basic).to be_an_instance_of SymEngine::Basic
16
+ end
17
+ end
18
+ end
19
+
20
+ describe 'binary operations' do
21
+ before :each do
22
+ @a = SymEngine::Symbol.new('x')
23
+ @b = SymEngine::Symbol.new('y')
24
+ end
25
+ describe '#+' do
26
+ context 'with another initialised Basic object as argument' do
27
+ it 'returns a initialised Basic object that is result of
28
+ self added to the argument' do
29
+ c = @a + @b
30
+ expect(c).to be_an_instance_of SymEngine::Basic
31
+ expect(c.to_s).to eql('x + y')
32
+ end
33
+ end
34
+ end
35
+ describe '#-' do
36
+ context 'with another initialised Basic object as argument' do
37
+ it 'returns a initialised Basic object that is result of
38
+ argument subtracted from self' do
39
+ c = @a - @b
40
+ expect(c).to be_an_instance_of SymEngine::Basic
41
+ expect(c.to_s).to eql('x - y')
42
+ end
43
+ end
44
+ end
45
+ describe '#*' do
46
+ context 'with another initialised Basic object as argument' do
47
+ it 'returns a initialised Basic object that is result of
48
+ self multiplied by the argument' do
49
+ c = @a * @b
50
+ expect(c).to be_an_instance_of SymEngine::Basic
51
+ expect(c.to_s).to eql('x*y')
52
+ end
53
+ end
54
+ end
55
+ describe '#/' do
56
+ context 'with another initialised Basic object as argument' do
57
+ it 'returns a initialised Basic object that is result of
58
+ self divided by the argument' do
59
+ c = @a / @b
60
+ expect(c).to be_an_instance_of SymEngine::Basic
61
+ expect(c.to_s).to eql('x/y')
62
+ end
63
+ end
64
+ end
65
+ describe '#**' do
66
+ context 'with another initialised Basic object as argument' do
67
+ it 'returns a initialised Basic object that is result of
68
+ self raised to the power of argument' do
69
+ c = @a**@b
70
+ expect(c).to be_an_instance_of SymEngine::Basic
71
+ expect(c.to_s).to eql('x**y')
72
+ end
73
+ end
74
+ end
75
+ describe '#diff' do
76
+ context 'with another initialised Basic object as argument' do
77
+ it 'differentiates self with respect to the argument
78
+ and returns the result' do
79
+ a = @a**3
80
+ c = a.diff(@a)
81
+ expect(c).to be_an_instance_of SymEngine::Basic
82
+ expect(c).to eq(3 * @a**2)
83
+ expect(a.diff(2)).to be_nil
84
+ end
85
+ end
86
+ end
87
+ describe '#==' do
88
+ context 'with another initialised Basic object as argument' do
89
+ it 'returns true if they are the same expression
90
+ false if not' do
91
+ a = SymEngine::Symbol.new('x')
92
+ b = SymEngine::Symbol.new('y')
93
+ c = ((a * b) == (@a * @b))
94
+ expect(c).to be true
95
+ end
96
+ end
97
+ end
98
+ describe '#eql?' do
99
+ context 'with another initialised Basic object as argument' do
100
+ it 'returns true if they are the same expression
101
+ false if not' do
102
+ a = SymEngine::Symbol.new('x')
103
+ b = SymEngine::Symbol.new('y')
104
+ c = ((a * b).eql?(@a * @b))
105
+ expect(c).to be true
106
+ end
107
+ end
108
+ end
109
+ describe '#!=' do
110
+ context 'with another initialised Basic object as argument' do
111
+ it 'returns true is they are not the same expression
112
+ false if they are' do |_variable|
113
+ a = SymEngine::Symbol.new('x')
114
+ b = SymEngine::Symbol.new('y')
115
+ c = ((a * b) != (@a * @b))
116
+ expect(c).to be false
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ describe 'unary operations' do
123
+ before :each do
124
+ @x = SymEngine::Symbol.new('a')
125
+ end
126
+ describe '#-@' do
127
+ context "doesn't take any argument" do
128
+ it 'returns the negation of self' do
129
+ p = -@x
130
+ expect(p).to be_an_instance_of SymEngine::Basic
131
+ expect(p.to_s).to eql('-a')
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ describe '#args' do
138
+ context 'with nothing as argument' do
139
+ it 'returns array of arguments' do
140
+ x = SymEngine::Symbol.new('x')
141
+ y = SymEngine::Symbol.new('y')
142
+ z = SymEngine::Symbol.new('z')
143
+ e = (x**y + z)
144
+ f = e.args
145
+ expect(f).to be_an_instance_of Array
146
+ expect(f.length).to be 2
147
+ expect(f.to_set).to eql([x**y, z].to_set)
148
+ end
149
+ end
150
+ end
151
+
152
+ describe '#free_symbols' do
153
+ context 'with nothing as argument' do
154
+ it 'returns the set of symbols' do
155
+ x = SymEngine::Symbol.new('x')
156
+ y = SymEngine::Symbol.new('y')
157
+ z = SymEngine::Symbol.new('z')
158
+ e = (x**y / z)
159
+ f = e.free_symbols
160
+ expect(f).to be_an_instance_of Set
161
+ expect(f.length).to be 3
162
+ expect(f).to eql([x, y, z].to_set)
163
+ end
164
+ end
165
+ end
166
+
167
+ describe '#expand' do
168
+ context 'with nothing as argument' do
169
+ it 'returns the expanded form' do
170
+ x = SymEngine::Symbol.new('x')
171
+ y = SymEngine::Symbol.new('y')
172
+ z = SymEngine::Symbol.new('z')
173
+ e = (x + y + z) * (x + y + z)
174
+ f = e.expand
175
+ expect(e.to_s).to eql('(x + y + z)**2')
176
+ expect(f).to be_an_instance_of SymEngine::Basic
177
+ expect(f.to_s).to eql('2*x*y + 2*x*z + 2*y*z + x**2 + y**2 + z**2')
178
+ expect(e == f).to be false
179
+ end
180
+ end
181
+ end
182
+
183
+ describe '#subs' do
184
+ before :each do
185
+ @x = SymEngine::Symbol.new('x')
186
+ @y = SymEngine::Symbol.new('y')
187
+ @z = SymEngine::Symbol.new('z')
188
+ @e = @x + @y + @z
189
+ end
190
+
191
+ context 'with two basic objects as argument' do
192
+ it 'returns the expression with first
193
+ substituted with second in self' do
194
+ expect(@e.subs(@x, @y)).to eql(2 * @y + @z)
195
+ end
196
+ end
197
+
198
+ context 'with a Hash as argument' do
199
+ it 'returns the expression with
200
+ each key subtituted with its mapped value' do
201
+ expect(@e.subs(@x => @y, @z => @y)).to eql(3 * @y)
202
+ k = SymEngine::Symbol.new('k')
203
+ e = @e.subs(@x => k, @y => k / 2, @z => 2 * k)
204
+ expect(e).to eql((7 * k) / 2)
205
+ end
206
+ end
207
+
208
+ context ' with less than one or more than two or wrong argument' do
209
+ it 'raises errors' do
210
+ expect { @e.subs }.to raise_error(ArgumentError)
211
+ expect { @e.subs(@x, @y, @z) }.to raise_error(ArgumentError)
212
+ expect { @e.subs(@x) }.to raise_error(TypeError)
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end