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,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