symengine 0.0.0
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.
- 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:
|