symengine 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CMakeLists.txt +15 -0
- data/LICENSE +20 -0
- data/README.md +55 -0
- data/bin/callgrind_test.sh +34 -0
- data/bin/gdb.sh +10 -0
- data/bin/valgrind_test.sh +31 -0
- data/ext/symengine/CMakeLists.txt +25 -0
- data/ext/symengine/extconf.rb +1 -0
- data/ext/symengine/ruby_basic.c +254 -0
- data/ext/symengine/ruby_basic.h +53 -0
- data/ext/symengine/ruby_integer.c +8 -0
- data/ext/symengine/ruby_integer.h +8 -0
- data/ext/symengine/ruby_rational.c +23 -0
- data/ext/symengine/ruby_rational.h +8 -0
- data/ext/symengine/ruby_symbol.c +13 -0
- data/ext/symengine/ruby_symbol.h +8 -0
- data/ext/symengine/symengine.c +49 -0
- data/ext/symengine/symengine.h +15 -0
- data/ext/symengine/symengine_macros.c +49 -0
- data/ext/symengine/symengine_macros.h +21 -0
- data/lib/symengine.rb +14 -0
- data/lib/symengine/basic.rb +9 -0
- data/lib/symengine/iruby.rb +9 -0
- metadata +127 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e07b59a3ec9f3d16e63d9479290a8b4480ee721c
|
4
|
+
data.tar.gz: cfefed3f9860bad0a2a078968699c391d18df4d5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 38311d6fb31cd3c4fbc01223c7e39bb75e2fdfdb1d4e9501d76fb70e09f4e77cefa86f6c355a2abc4b54a6db13f18c8a7b3d67569f3b582d73decb16f8c2b146
|
7
|
+
data.tar.gz: 5486a9ad6d3fa9f7cb25ea49b2b89b7a6aff0174da7bf3259c8ddcc29a31a6ef5dd39de7e59b9f4d3ece7533d4ac5b0fbea01517ec07e535e9dd0c0a83705f3a
|
data/CMakeLists.txt
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
cmake_minimum_required(VERSION 2.8)
|
2
|
+
project(ruby_wrapper)
|
3
|
+
|
4
|
+
set(CMAKE_PREFIX_PATH ${SymEngine_DIR} ${CMAKE_PREFIX_PATH})
|
5
|
+
find_package(SymEngine 0.1.0 REQUIRED CONFIG
|
6
|
+
PATH_SUFFIXES lib/cmake/symengine CMake/)
|
7
|
+
set(CMAKE_BUILD_TYPE ${SYMENGINE_BUILD_TYPE})
|
8
|
+
set(CMAKE_CXX_FLAGS_RELEASE ${SYMENGINE_CXX_FLAGS_RELEASE})
|
9
|
+
set(CMAKE_CXX_FLAGS_DEBUG ${SYMENGINE_CXX_FLAGS_DEBUG})
|
10
|
+
include_directories(${SYMENGINE_INCLUDE_DIRS})
|
11
|
+
|
12
|
+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
13
|
+
find_package(Ruby REQUIRED)
|
14
|
+
|
15
|
+
add_subdirectory(ext/symengine)
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2015 SymEngine Development Team
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
20
|
+
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
## SymEngine Ruby Wrappers
|
2
|
+
|
3
|
+
Ruby wrappers gem for SymEngine, a fast symbolic manipulation library, written in C++. https://github.com/sympy/symengine
|
4
|
+
|
5
|
+
### Installation
|
6
|
+
|
7
|
+
#### Prerequisites
|
8
|
+
|
9
|
+
- C++ compiler - See supported [compilers](https://github.com/sympy/symengine/wiki/Compiler-Support)
|
10
|
+
|
11
|
+
- CMake - with executable folder in the `PATH` variable
|
12
|
+
|
13
|
+
- libsymengine - See build [instructions](https://github.com/sympy/symengine/wiki/Building-SymEngine)
|
14
|
+
|
15
|
+
#### Installing
|
16
|
+
|
17
|
+
- Simply do,
|
18
|
+
|
19
|
+
gem install symengine
|
20
|
+
|
21
|
+
- If `libsymengine` is not found, you can give the installation directory or build directory by doing,
|
22
|
+
|
23
|
+
gem install symengine -- -DSymEngine_DIR=/path/to/symengine/root
|
24
|
+
|
25
|
+
### Development
|
26
|
+
* Install bundler by `gem install bundler`
|
27
|
+
* Execute `bundle install` this will install the gems required
|
28
|
+
* Build the gem, `gem build symengine.gemspec`
|
29
|
+
* Install the gem, `gem install symengine-0.0.0.gem`
|
30
|
+
|
31
|
+
### Using the extensions
|
32
|
+
SymEngine is a module in the extensions, and the classes are a part of it. So
|
33
|
+
first you fire up the interpreter and load the file
|
34
|
+
``` ruby
|
35
|
+
~$ irb
|
36
|
+
2.2.0 :001 > require 'symengine'
|
37
|
+
=> true
|
38
|
+
|
39
|
+
```
|
40
|
+
Go ahead and try a function
|
41
|
+
``` ruby
|
42
|
+
2.2.0 :002 > SymEngine.ascii_art
|
43
|
+
|
44
|
+
_____ _____ _
|
45
|
+
| __|_ _ _____| __|___ ___|_|___ ___
|
46
|
+
|__ | | | | __| | . | | | -_|
|
47
|
+
|_____|_ |_|_|_|_____|_|_|_ |_|_|_|___|
|
48
|
+
|___| |___|
|
49
|
+
=> nil
|
50
|
+
```
|
51
|
+
or create a variable
|
52
|
+
``` ruby
|
53
|
+
2.2.0 :003 > basic = SymEngine::Symbol.new("x")
|
54
|
+
=> #<SymEngine::Symbol:0x0000000274d608>
|
55
|
+
```
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# Note: use this script from the root dir of the ruby wrappers gem as
|
4
|
+
# your current dir.
|
5
|
+
|
6
|
+
# Callgrind is a profiling tool that records the call history among functions
|
7
|
+
# in a program's run as a call-graph. By default, the collected data consists
|
8
|
+
# of the number of instructions executed, their relationship to source lines,
|
9
|
+
# the caller/callee relationship between functions, and the numbers of such
|
10
|
+
# calls.
|
11
|
+
|
12
|
+
#--tool=callgrind: ask valgrind to use callgrind profiler plugin
|
13
|
+
#--dump-instr=yes: specifies that event counting should be performed at per-instruction
|
14
|
+
# granularity. This allows for assembly code annotation. The results can
|
15
|
+
# only be displayed by KCachegrind.
|
16
|
+
#--simulate-cache=yes: runs with cache simulation
|
17
|
+
#--collect-jumps=yes: specifies whether information for (conditional) jumps should be
|
18
|
+
# collected. You have to use KCachegrind to get jump arrows in the
|
19
|
+
# annotated code.
|
20
|
+
valgrind \
|
21
|
+
--tool=callgrind \
|
22
|
+
--dump-instr=yes \
|
23
|
+
--simulate-cache=yes \
|
24
|
+
--collect-jumps=yes \
|
25
|
+
ruby -S rspec spec
|
26
|
+
|
27
|
+
# After program termination, a profile data file named callgrind.out.<pid> is generated,
|
28
|
+
# where pid is the process ID of the program being profiled. The data file contains
|
29
|
+
# information about the calls made in the program among the functions executed
|
30
|
+
|
31
|
+
# To generate a function-by-function summary, use
|
32
|
+
# `callfrind_annotate callgrind.out.<pid>`
|
33
|
+
# or use Kcachegrind, the Call Graph Viewer.
|
34
|
+
# documentation: http://kcachegrind.sourceforge.net/html/Documentation.html
|
data/bin/gdb.sh
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# Note: use this script from the root dir of the ruby wrappers gem as
|
4
|
+
# your current dir.
|
5
|
+
|
6
|
+
if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" ]]; then
|
7
|
+
echo "bin/gdb.sh [file-name you want to run with rspec]"
|
8
|
+
exit 0
|
9
|
+
fi
|
10
|
+
gdb -ex=r --args ruby -S rspec $1
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# Note: use this script from the root dir of the ruby wrappers gem as
|
4
|
+
# your current dir.
|
5
|
+
|
6
|
+
# Memcheck is a memory error detector which can detect problems like
|
7
|
+
# accessing memory you shouldn't, using undefined values, incorrect
|
8
|
+
# freeing of heap memory, overlapping source and destination pointers
|
9
|
+
# in `memcpy` and related functions, memory leaks, etc.
|
10
|
+
|
11
|
+
# --tool=memcheck: specifies that memcheck is the tool to be used
|
12
|
+
# --num-callers=15: specifies the amount of stack-trace to show. Can be
|
13
|
+
# set to larger values if the stack trace is not big
|
14
|
+
# enough
|
15
|
+
# partial-loads-ok and undef-value-errors are necessary to ignore
|
16
|
+
# spurious (and eminently ignorable) warnings from the ruby
|
17
|
+
# interpreter. The MRI does a lot of funky things in the name of speed,
|
18
|
+
# like using uninitialized variables and reading past the ends of
|
19
|
+
# malloced blocks that aren't on an 8-byte boundary. For advanced info:
|
20
|
+
# http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress
|
21
|
+
valgrind \
|
22
|
+
--tool=memcheck \
|
23
|
+
--num-callers=15 \
|
24
|
+
--partial-loads-ok=yes \
|
25
|
+
--undef-value-errors=no \
|
26
|
+
ruby -S rspec spec
|
27
|
+
|
28
|
+
# additional options like `--leak-check=full` can be used if needed.
|
29
|
+
# If --leak-check=full is specified, Memcheck will give details for
|
30
|
+
# each definitely lost or possibly lost block, including where it was
|
31
|
+
# allocated.
|
@@ -0,0 +1,25 @@
|
|
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_LIBRARIES})
|
14
|
+
set_target_properties(symengine_ruby PROPERTIES
|
15
|
+
PREFIX ""
|
16
|
+
OUTPUT_NAME "symengine"
|
17
|
+
LIBRARY_OUTPUT_DIRECTORY "${ruby_wrapper_BINARY_DIR}/lib/symengine"
|
18
|
+
)
|
19
|
+
|
20
|
+
# Ruby gems require a install target.
|
21
|
+
install(TARGETS symengine_ruby
|
22
|
+
RUNTIME DESTINATION lib/symengine
|
23
|
+
ARCHIVE DESTINATION lib/symengine
|
24
|
+
LIBRARY DESTINATION lib/symengine
|
25
|
+
)
|
@@ -0,0 +1 @@
|
|
1
|
+
exec 'cmake -DCMAKE_INSTALL_PREFIX=../../ %s ../../ ' % [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,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,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,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
|
+
}
|
@@ -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_
|
data/lib/symengine.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'symengine/symengine'
|
2
|
+
require 'symengine/iruby'
|
3
|
+
require 'symengine/basic'
|
4
|
+
|
5
|
+
module SymEngine
|
6
|
+
def SymEngine.ascii_art
|
7
|
+
puts "
|
8
|
+
_____ _____ _
|
9
|
+
| __|_ _ _____| __|___ ___|_|___ ___
|
10
|
+
|__ | | | | __| | . | | | -_|
|
11
|
+
|_____|_ |_|_|_|_____|_|_|_ |_|_|_|___|
|
12
|
+
|___| |___| "
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: symengine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Abinash Meher
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: test-unit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.0'
|
69
|
+
description: This gem provides a Ruby interface for SymEngine, a fast C++ library
|
70
|
+
for symbolic manipulation, so that the you can use the features of SymEngine in
|
71
|
+
ruby.
|
72
|
+
email:
|
73
|
+
- abinashdakshana999@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions:
|
76
|
+
- ext/symengine/extconf.rb
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- CMakeLists.txt
|
80
|
+
- LICENSE
|
81
|
+
- README.md
|
82
|
+
- bin/callgrind_test.sh
|
83
|
+
- bin/gdb.sh
|
84
|
+
- bin/valgrind_test.sh
|
85
|
+
- ext/symengine/CMakeLists.txt
|
86
|
+
- ext/symengine/extconf.rb
|
87
|
+
- ext/symengine/ruby_basic.c
|
88
|
+
- ext/symengine/ruby_basic.h
|
89
|
+
- ext/symengine/ruby_integer.c
|
90
|
+
- ext/symengine/ruby_integer.h
|
91
|
+
- ext/symengine/ruby_rational.c
|
92
|
+
- ext/symengine/ruby_rational.h
|
93
|
+
- ext/symengine/ruby_symbol.c
|
94
|
+
- ext/symengine/ruby_symbol.h
|
95
|
+
- ext/symengine/symengine.c
|
96
|
+
- ext/symengine/symengine.h
|
97
|
+
- ext/symengine/symengine_macros.c
|
98
|
+
- ext/symengine/symengine_macros.h
|
99
|
+
- lib/symengine.rb
|
100
|
+
- lib/symengine/basic.rb
|
101
|
+
- lib/symengine/iruby.rb
|
102
|
+
homepage: https://github.com/sympy/symengine
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.4.6
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: Ruby interface for SymEngine, a fast C++ library for symbolic manipulation
|
126
|
+
test_files: []
|
127
|
+
has_rdoc:
|