symengine 0.14.0__cp313-cp313t-win_amd64.whl
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.
- symengine/lib/flint-19.dll +0 -0
- symengine/lib/libgcc_s_seh-1.dll +0 -0
- symengine/lib/libgmp-10.dll +0 -0
- symengine/lib/libmpc-3.dll +0 -0
- symengine/lib/libmpfr-6.dll +0 -0
- symengine/lib/libwinpthread-1.dll +0 -0
- symengine/lib/pywrapper.h +220 -0
- symengine/lib/symengine.pxd +955 -0
- symengine/lib/symengine_wrapper.cp313t-win_amd64.lib +0 -0
- symengine/lib/symengine_wrapper.cp313t-win_amd64.pyd +0 -0
- symengine/lib/symengine_wrapper.pxd +78 -0
- symengine/lib/zlib.dll +0 -0
- symengine/lib/zstd.dll +0 -0
- symengine-0.14.0.data/purelib/symengine/__init__.py +79 -0
- symengine-0.14.0.data/purelib/symengine/functions.py +10 -0
- symengine-0.14.0.data/purelib/symengine/lib/__init__.py +0 -0
- symengine-0.14.0.data/purelib/symengine/printing.py +33 -0
- symengine-0.14.0.data/purelib/symengine/sympy_compat.py +4 -0
- symengine-0.14.0.data/purelib/symengine/test_utilities.py +95 -0
- symengine-0.14.0.data/purelib/symengine/tests/__init__.py +0 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_arit.py +261 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_cse.py +17 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_dict_basic.py +28 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_eval.py +67 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_expr.py +28 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_functions.py +432 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_lambdify.py +863 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_logic.py +124 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_matrices.py +757 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_ntheory.py +254 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_number.py +186 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_pickling.py +59 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_printing.py +38 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_sage.py +175 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_series_expansion.py +22 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_sets.py +118 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_solve.py +25 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_subs.py +82 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_symbol.py +179 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_sympify.py +63 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_sympy_compat.py +200 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_sympy_conv.py +835 -0
- symengine-0.14.0.data/purelib/symengine/tests/test_var.py +68 -0
- symengine-0.14.0.data/purelib/symengine/utilities.py +280 -0
- symengine-0.14.0.dist-info/AUTHORS +40 -0
- symengine-0.14.0.dist-info/LICENSE +430 -0
- symengine-0.14.0.dist-info/METADATA +39 -0
- symengine-0.14.0.dist-info/RECORD +50 -0
- symengine-0.14.0.dist-info/WHEEL +5 -0
- symengine-0.14.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
# Tests for var are in their own file, because var pollutes global namespace.
|
2
|
+
|
3
|
+
from symengine import Symbol, var
|
4
|
+
from symengine.test_utilities import raises
|
5
|
+
# make z1 with call-depth = 1
|
6
|
+
|
7
|
+
|
8
|
+
def _make_z1():
|
9
|
+
var("z1")
|
10
|
+
|
11
|
+
# make z2 with call-depth = 2
|
12
|
+
|
13
|
+
|
14
|
+
def __make_z2():
|
15
|
+
var("z2")
|
16
|
+
|
17
|
+
|
18
|
+
def _make_z2():
|
19
|
+
__make_z2()
|
20
|
+
|
21
|
+
|
22
|
+
def test_var():
|
23
|
+
var("a")
|
24
|
+
assert a == Symbol("a")
|
25
|
+
|
26
|
+
var("b bb cc zz _x")
|
27
|
+
assert b == Symbol("b")
|
28
|
+
assert bb == Symbol("bb")
|
29
|
+
assert cc == Symbol("cc")
|
30
|
+
assert zz == Symbol("zz")
|
31
|
+
assert _x == Symbol("_x")
|
32
|
+
|
33
|
+
v = var(['d', 'e', 'fg'])
|
34
|
+
assert d == Symbol('d')
|
35
|
+
assert e == Symbol('e')
|
36
|
+
assert fg == Symbol('fg')
|
37
|
+
|
38
|
+
# check return value
|
39
|
+
assert v == [d, e, fg]
|
40
|
+
|
41
|
+
|
42
|
+
def test_var_global_namespace():
|
43
|
+
# see if var() really injects into global namespace
|
44
|
+
raises(NameError, lambda: z1)
|
45
|
+
_make_z1()
|
46
|
+
assert z1 == Symbol("z1")
|
47
|
+
|
48
|
+
raises(NameError, lambda: z2)
|
49
|
+
_make_z2()
|
50
|
+
assert z2 == Symbol("z2")
|
51
|
+
|
52
|
+
|
53
|
+
def test_var_return():
|
54
|
+
raises(ValueError, lambda: var(''))
|
55
|
+
v2 = var('q')
|
56
|
+
v3 = var('q p')
|
57
|
+
|
58
|
+
assert v2 == Symbol('q')
|
59
|
+
assert v3 == (Symbol('q'), Symbol('p'))
|
60
|
+
|
61
|
+
|
62
|
+
def test_var_accepts_comma():
|
63
|
+
v1 = var('x y z')
|
64
|
+
v2 = var('x,y,z')
|
65
|
+
v3 = var('x,y z')
|
66
|
+
|
67
|
+
assert v1 == v2
|
68
|
+
assert v1 == v3
|
@@ -0,0 +1,280 @@
|
|
1
|
+
from .lib.symengine_wrapper import Symbol, Basic
|
2
|
+
from itertools import combinations, permutations, product, product as cartes
|
3
|
+
import re as _re
|
4
|
+
import string
|
5
|
+
import sys
|
6
|
+
|
7
|
+
|
8
|
+
_range = _re.compile('([0-9]*:[0-9]+|[a-zA-Z]?:[a-zA-Z])')
|
9
|
+
|
10
|
+
|
11
|
+
def symbols(names, **args):
|
12
|
+
r"""
|
13
|
+
Transform strings into instances of :class:`Symbol` class.
|
14
|
+
:func:`symbols` function returns a sequence of symbols with names taken
|
15
|
+
from ``names`` argument, which can be a comma or whitespace delimited
|
16
|
+
string, or a sequence of strings::
|
17
|
+
>>> from symengine import symbols
|
18
|
+
>>> x, y, z = symbols('x,y,z')
|
19
|
+
>>> a, b, c = symbols('a b c')
|
20
|
+
The type of output is dependent on the properties of input arguments::
|
21
|
+
>>> symbols('x')
|
22
|
+
x
|
23
|
+
>>> symbols('x,')
|
24
|
+
(x,)
|
25
|
+
>>> symbols('x,y')
|
26
|
+
(x, y)
|
27
|
+
>>> symbols(('a', 'b', 'c'))
|
28
|
+
(a, b, c)
|
29
|
+
>>> symbols(['a', 'b', 'c'])
|
30
|
+
[a, b, c]
|
31
|
+
>>> symbols(set(['a', 'b', 'c']))
|
32
|
+
set([a, b, c])
|
33
|
+
If an iterable container is needed for a single symbol, set the ``seq``
|
34
|
+
argument to ``True`` or terminate the symbol name with a comma::
|
35
|
+
>>> symbols('x', seq=True)
|
36
|
+
(x,)
|
37
|
+
To reduce typing, range syntax is supported to create indexed symbols.
|
38
|
+
Ranges are indicated by a colon and the type of range is determined by
|
39
|
+
the character to the right of the colon. If the character is a digit
|
40
|
+
then all contiguous digits to the left are taken as the nonnegative
|
41
|
+
starting value (or 0 if there is no digit left of the colon) and all
|
42
|
+
contiguous digits to the right are taken as 1 greater than the ending
|
43
|
+
value::
|
44
|
+
>>> symbols('x:10')
|
45
|
+
(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9)
|
46
|
+
>>> symbols('x5:10')
|
47
|
+
(x5, x6, x7, x8, x9)
|
48
|
+
>>> symbols('x5(:2)')
|
49
|
+
(x50, x51)
|
50
|
+
>>> symbols('x5:10,y:5')
|
51
|
+
(x5, x6, x7, x8, x9, y0, y1, y2, y3, y4)
|
52
|
+
>>> symbols(('x5:10', 'y:5'))
|
53
|
+
((x5, x6, x7, x8, x9), (y0, y1, y2, y3, y4))
|
54
|
+
If the character to the right of the colon is a letter, then the single
|
55
|
+
letter to the left (or 'a' if there is none) is taken as the start
|
56
|
+
and all characters in the lexicographic range *through* the letter to
|
57
|
+
the right are used as the range::
|
58
|
+
>>> symbols('x:z')
|
59
|
+
(x, y, z)
|
60
|
+
>>> symbols('x:c') # null range
|
61
|
+
()
|
62
|
+
>>> symbols('x(:c)')
|
63
|
+
(xa, xb, xc)
|
64
|
+
>>> symbols(':c')
|
65
|
+
(a, b, c)
|
66
|
+
>>> symbols('a:d, x:z')
|
67
|
+
(a, b, c, d, x, y, z)
|
68
|
+
>>> symbols(('a:d', 'x:z'))
|
69
|
+
((a, b, c, d), (x, y, z))
|
70
|
+
Multiple ranges are supported; contiguous numerical ranges should be
|
71
|
+
separated by parentheses to disambiguate the ending number of one
|
72
|
+
range from the starting number of the next::
|
73
|
+
>>> symbols('x:2(1:3)')
|
74
|
+
(x01, x02, x11, x12)
|
75
|
+
>>> symbols(':3:2') # parsing is from left to right
|
76
|
+
(00, 01, 10, 11, 20, 21)
|
77
|
+
Only one pair of parentheses surrounding ranges are removed, so to
|
78
|
+
include parentheses around ranges, double them. And to include spaces,
|
79
|
+
commas, or colons, escape them with a backslash::
|
80
|
+
>>> symbols('x((a:b))')
|
81
|
+
(x(a), x(b))
|
82
|
+
>>> symbols('x(:1\,:2)') # or 'x((:1)\,(:2))'
|
83
|
+
(x(0,0), x(0,1))
|
84
|
+
"""
|
85
|
+
result = []
|
86
|
+
|
87
|
+
if isinstance(names, str):
|
88
|
+
marker = 0
|
89
|
+
literals = [r'\,', r'\:', r'\ ']
|
90
|
+
for i in range(len(literals)):
|
91
|
+
lit = literals.pop(0)
|
92
|
+
if lit in names:
|
93
|
+
while chr(marker) in names:
|
94
|
+
marker += 1
|
95
|
+
lit_char = chr(marker)
|
96
|
+
marker += 1
|
97
|
+
names = names.replace(lit, lit_char)
|
98
|
+
literals.append((lit_char, lit[1:]))
|
99
|
+
|
100
|
+
def literal(s):
|
101
|
+
if literals:
|
102
|
+
for c, l in literals:
|
103
|
+
s = s.replace(c, l)
|
104
|
+
return s
|
105
|
+
|
106
|
+
names = names.strip()
|
107
|
+
as_seq = names.endswith(',')
|
108
|
+
if as_seq:
|
109
|
+
names = names[:-1].rstrip()
|
110
|
+
if not names:
|
111
|
+
raise ValueError('no symbols given')
|
112
|
+
|
113
|
+
# split on commas
|
114
|
+
names = [n.strip() for n in names.split(',')]
|
115
|
+
if not all(n for n in names):
|
116
|
+
raise ValueError('missing symbol between commas')
|
117
|
+
# split on spaces
|
118
|
+
for i in range(len(names) - 1, -1, -1):
|
119
|
+
names[i: i + 1] = names[i].split()
|
120
|
+
|
121
|
+
cls = args.pop('cls', Symbol)
|
122
|
+
seq = args.pop('seq', as_seq)
|
123
|
+
|
124
|
+
for name in names:
|
125
|
+
if not name:
|
126
|
+
raise ValueError('missing symbol')
|
127
|
+
|
128
|
+
if ':' not in name:
|
129
|
+
symbol = cls(literal(name), **args)
|
130
|
+
result.append(symbol)
|
131
|
+
continue
|
132
|
+
|
133
|
+
split = _range.split(name)
|
134
|
+
# remove 1 layer of bounding parentheses around ranges
|
135
|
+
for i in range(len(split) - 1):
|
136
|
+
if i and ':' in split[i] and split[i] != ':' and \
|
137
|
+
split[i - 1].endswith('(') and \
|
138
|
+
split[i + 1].startswith(')'):
|
139
|
+
split[i - 1] = split[i - 1][:-1]
|
140
|
+
split[i + 1] = split[i + 1][1:]
|
141
|
+
for i, s in enumerate(split):
|
142
|
+
if ':' in s:
|
143
|
+
if s[-1].endswith(':'):
|
144
|
+
raise ValueError('missing end range')
|
145
|
+
a, b = s.split(':')
|
146
|
+
if b[-1] in string.digits:
|
147
|
+
a = 0 if not a else int(a)
|
148
|
+
b = int(b)
|
149
|
+
split[i] = [str(c) for c in range(a, b)]
|
150
|
+
else:
|
151
|
+
a = a or 'a'
|
152
|
+
split[i] = [string.ascii_letters[c] for c in range(
|
153
|
+
string.ascii_letters.index(a),
|
154
|
+
string.ascii_letters.index(b) + 1)] # inclusive
|
155
|
+
if not split[i]:
|
156
|
+
break
|
157
|
+
else:
|
158
|
+
split[i] = [s]
|
159
|
+
else:
|
160
|
+
seq = True
|
161
|
+
if len(split) == 1:
|
162
|
+
names = split[0]
|
163
|
+
else:
|
164
|
+
names = [''.join(s) for s in cartes(*split)]
|
165
|
+
if literals:
|
166
|
+
result.extend([cls(literal(s), **args) for s in names])
|
167
|
+
else:
|
168
|
+
result.extend([cls(s, **args) for s in names])
|
169
|
+
|
170
|
+
if not seq and len(result) <= 1:
|
171
|
+
if not result:
|
172
|
+
return ()
|
173
|
+
return result[0]
|
174
|
+
|
175
|
+
return tuple(result)
|
176
|
+
else:
|
177
|
+
for name in names:
|
178
|
+
result.append(symbols(name, **args))
|
179
|
+
|
180
|
+
return type(names)(result)
|
181
|
+
|
182
|
+
|
183
|
+
def var(names, **args):
|
184
|
+
"""
|
185
|
+
Create symbols and inject them into the global namespace.
|
186
|
+
|
187
|
+
INPUT:
|
188
|
+
- s -- a string, either a single variable name, or
|
189
|
+
- a space separated list of variable names, or
|
190
|
+
- a list of variable names.
|
191
|
+
|
192
|
+
This calls :func:`symbols` with the same arguments and puts the results
|
193
|
+
into the *global* namespace. It's recommended not to use :func:`var` in
|
194
|
+
library code, where :func:`symbols` has to be used::
|
195
|
+
|
196
|
+
Examples
|
197
|
+
========
|
198
|
+
|
199
|
+
>>> from symengine import var
|
200
|
+
|
201
|
+
>>> var('x')
|
202
|
+
x
|
203
|
+
>>> x
|
204
|
+
x
|
205
|
+
|
206
|
+
>>> var('a,ab,abc')
|
207
|
+
(a, ab, abc)
|
208
|
+
>>> abc
|
209
|
+
abc
|
210
|
+
|
211
|
+
See :func:`symbols` documentation for more details on what kinds of
|
212
|
+
arguments can be passed to :func:`var`.
|
213
|
+
|
214
|
+
"""
|
215
|
+
def traverse(symbols, frame):
|
216
|
+
"""Recursively inject symbols to the global namespace. """
|
217
|
+
for symbol in symbols:
|
218
|
+
if isinstance(symbol, Basic):
|
219
|
+
frame.f_globals[symbol.__str__()] = symbol
|
220
|
+
# Once we hace an undefined function class
|
221
|
+
# implemented, put a check for function here
|
222
|
+
else:
|
223
|
+
traverse(symbol, frame)
|
224
|
+
|
225
|
+
from inspect import currentframe
|
226
|
+
frame = currentframe().f_back
|
227
|
+
|
228
|
+
try:
|
229
|
+
syms = symbols(names, **args)
|
230
|
+
|
231
|
+
if syms is not None:
|
232
|
+
if isinstance(syms, Basic):
|
233
|
+
frame.f_globals[syms.__str__()] = syms
|
234
|
+
# Once we hace an undefined function class
|
235
|
+
# implemented, put a check for function here
|
236
|
+
else:
|
237
|
+
traverse(syms, frame)
|
238
|
+
finally:
|
239
|
+
del frame # break cyclic dependencies as stated in inspect docs
|
240
|
+
|
241
|
+
return syms
|
242
|
+
|
243
|
+
|
244
|
+
class NotIterable:
|
245
|
+
"""
|
246
|
+
Use this as mixin when creating a class which is not supposed to return
|
247
|
+
true when iterable() is called on its instances. I.e. avoid infinite loop
|
248
|
+
when calling e.g. list() on the instance
|
249
|
+
"""
|
250
|
+
pass
|
251
|
+
|
252
|
+
|
253
|
+
def iterable(i, exclude=(str, dict, NotIterable)):
|
254
|
+
"""
|
255
|
+
Return a boolean indicating whether ``i`` is SymPy iterable.
|
256
|
+
True also indicates that the iterator is finite, i.e. you e.g.
|
257
|
+
call list(...) on the instance.
|
258
|
+
|
259
|
+
When SymPy is working with iterables, it is almost always assuming
|
260
|
+
that the iterable is not a string or a mapping, so those are excluded
|
261
|
+
by default. If you want a pure Python definition, make exclude=None. To
|
262
|
+
exclude multiple items, pass them as a tuple.
|
263
|
+
"""
|
264
|
+
try:
|
265
|
+
iter(i)
|
266
|
+
except TypeError:
|
267
|
+
return False
|
268
|
+
if exclude:
|
269
|
+
return not isinstance(i, exclude)
|
270
|
+
return True
|
271
|
+
|
272
|
+
|
273
|
+
def is_sequence(i):
|
274
|
+
"""
|
275
|
+
Return a boolean indicating whether ``i`` is a sequence in the SymPy
|
276
|
+
sense. If anything that fails the test below should be included as
|
277
|
+
being a sequence for your application, set 'include' to that object's
|
278
|
+
type; multiple types should be passed as a tuple of types.
|
279
|
+
"""
|
280
|
+
return hasattr(i, '__getitem__') and iterable(i)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
All people who contributed to symengine.py by sending at least a patch or more
|
2
|
+
(Note that this repository was a subfolder of symengine repo and early contributors
|
3
|
+
to the python bindings maybe listed in AUTHORS of symengine repo).
|
4
|
+
You can generate this file by: bin/update_authors.sh.
|
5
|
+
|
6
|
+
Ondřej Čertík <ondrej@certik.us>
|
7
|
+
Thilina Bandara Rathanyake <thilinarmtb@gmail.com>
|
8
|
+
Isuru Fernando <isuruf@gmail.com>
|
9
|
+
Sushant Hiray <hiraysushant@gmail.com>
|
10
|
+
Peter Brady <petertbrady@gmail.com>
|
11
|
+
Thilina Bandara Rathnayake <thilinarmtb@gmail.com>
|
12
|
+
Shivam Vats <shivamvats.iitkgp@gmail.com>
|
13
|
+
Sumith Kulal <sumith1896@gmail.com>
|
14
|
+
Connor Behan <connor.behan@gmail.com>
|
15
|
+
Ralf Stephan <ralf@ark.in-berlin.de>
|
16
|
+
Björn Dahlgren <bjodah@gmail.com>
|
17
|
+
Indrek Mandre <indrek@mare.ee>
|
18
|
+
Abhinav Agarwal <abhinavagarwal1996@gmail.com>
|
19
|
+
Matt Wala <wala1@illinois.edu>
|
20
|
+
Shikhar Jaiswal <jaiswalshikhar87@gmail.com>
|
21
|
+
Nilay Pochhi <pochhi.nilay@gmail.com>
|
22
|
+
xoviat <xoviat@users.noreply.github.com>
|
23
|
+
Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>
|
24
|
+
Moritz E. Beber <morbeb@biosustain.dtu.dk>
|
25
|
+
Alan Hu <alanlh2@illinois.edu>
|
26
|
+
Richard Otis <richard.otis@outlook.com>
|
27
|
+
Erik Jansson Agnvall <erikjansson90@gmail.com>
|
28
|
+
Simon Stelter <stelter@uni-bremen.de>
|
29
|
+
Jialin Ma <marlin@inventati.org>
|
30
|
+
Rikard Nordgren <rikard.nordgren@farmaci.uu.se>
|
31
|
+
Rohit Goswami <rgoswami@ieee.org>
|
32
|
+
Matthew Treinish <mtreinish@kortar.org>
|
33
|
+
Michał Górny <mgorny@gentoo.org>
|
34
|
+
Garming Sam <garming@catalyst.net.nz>
|
35
|
+
Pieter Eendebak <pieter.eendebak@gmail.com>
|
36
|
+
Ayush Kumar <ayushk7102@gmail.com>
|
37
|
+
Christian Clauss <cclauss@me.com>
|
38
|
+
Moraxyc <i@qaq.li>
|
39
|
+
Aaron Miller <78561124+aaron-skydio@users.noreply.github.com>
|
40
|
+
Firat Bezir <bezir.1@osu.edu>
|