ZhengyangZhang commited on
Commit
a6bc318
·
verified ·
1 Parent(s): 60619e3

Add files using upload-large-folder tool

Browse files
Files changed (50) hide show
  1. lib/python3.12/site-packages/sympy/printing/pretty/stringpict.py +537 -0
  2. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/__init__.cpython-312.pyc +0 -0
  3. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_aesaracode.cpython-312.pyc +0 -0
  4. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_c.cpython-312.pyc +0 -0
  5. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_codeprinter.cpython-312.pyc +0 -0
  6. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_conventions.cpython-312.pyc +0 -0
  7. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_cupy.cpython-312.pyc +0 -0
  8. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_cxx.cpython-312.pyc +0 -0
  9. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_dot.cpython-312.pyc +0 -0
  10. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_fortran.cpython-312.pyc +0 -0
  11. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_glsl.cpython-312.pyc +0 -0
  12. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_gtk.cpython-312.pyc +0 -0
  13. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_jax.cpython-312.pyc +0 -0
  14. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_jscode.cpython-312.pyc +0 -0
  15. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_julia.cpython-312.pyc +0 -0
  16. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_lambdarepr.cpython-312.pyc +0 -0
  17. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_llvmjit.cpython-312.pyc +0 -0
  18. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_maple.cpython-312.pyc +0 -0
  19. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_mathematica.cpython-312.pyc +0 -0
  20. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_numpy.cpython-312.pyc +0 -0
  21. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_octave.cpython-312.pyc +0 -0
  22. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_precedence.cpython-312.pyc +0 -0
  23. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_preview.cpython-312.pyc +0 -0
  24. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_pycode.cpython-312.pyc +0 -0
  25. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_python.cpython-312.pyc +0 -0
  26. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_rcode.cpython-312.pyc +0 -0
  27. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_repr.cpython-312.pyc +0 -0
  28. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_rust.cpython-312.pyc +0 -0
  29. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_smtlib.cpython-312.pyc +0 -0
  30. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_str.cpython-312.pyc +0 -0
  31. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_tableform.cpython-312.pyc +0 -0
  32. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_tensorflow.cpython-312.pyc +0 -0
  33. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_theanocode.cpython-312.pyc +0 -0
  34. lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_tree.cpython-312.pyc +0 -0
  35. lib/python3.12/site-packages/sympy/printing/tests/test_conventions.py +116 -0
  36. lib/python3.12/site-packages/sympy/printing/tests/test_gtk.py +18 -0
  37. lib/python3.12/site-packages/sympy/printing/tests/test_jax.py +370 -0
  38. lib/python3.12/site-packages/sympy/printing/tests/test_jscode.py +396 -0
  39. lib/python3.12/site-packages/sympy/printing/tests/test_julia.py +386 -0
  40. lib/python3.12/site-packages/sympy/printing/tests/test_latex.py +0 -0
  41. lib/python3.12/site-packages/sympy/printing/tests/test_llvmjit.py +224 -0
  42. lib/python3.12/site-packages/sympy/printing/tests/test_maple.py +381 -0
  43. lib/python3.12/site-packages/sympy/printing/tests/test_mathematica.py +287 -0
  44. lib/python3.12/site-packages/sympy/printing/tests/test_octave.py +515 -0
  45. lib/python3.12/site-packages/sympy/printing/tests/test_preview.py +38 -0
  46. lib/python3.12/site-packages/sympy/printing/tests/test_pycode.py +429 -0
  47. lib/python3.12/site-packages/sympy/printing/tests/test_repr.py +382 -0
  48. lib/python3.12/site-packages/sympy/printing/tests/test_smtlib.py +553 -0
  49. lib/python3.12/site-packages/sympy/printing/tests/test_str.py +1199 -0
  50. lib/python3.12/site-packages/sympy/printing/tests/test_tree.py +196 -0
lib/python3.12/site-packages/sympy/printing/pretty/stringpict.py ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Prettyprinter by Jurjen Bos.
2
+ (I hate spammers: mail me at pietjepuk314 at the reverse of ku.oc.oohay).
3
+ All objects have a method that create a "stringPict",
4
+ that can be used in the str method for pretty printing.
5
+
6
+ Updates by Jason Gedge (email <my last name> at cs mun ca)
7
+ - terminal_string() method
8
+ - minor fixes and changes (mostly to prettyForm)
9
+
10
+ TODO:
11
+ - Allow left/center/right alignment options for above/below and
12
+ top/center/bottom alignment options for left/right
13
+ """
14
+
15
+ import shutil
16
+
17
+ from .pretty_symbology import hobj, vobj, xsym, xobj, pretty_use_unicode, line_width, center
18
+ from sympy.utilities.exceptions import sympy_deprecation_warning
19
+
20
+ _GLOBAL_WRAP_LINE = None
21
+
22
+ class stringPict:
23
+ """An ASCII picture.
24
+ The pictures are represented as a list of equal length strings.
25
+ """
26
+ #special value for stringPict.below
27
+ LINE = 'line'
28
+
29
+ def __init__(self, s, baseline=0):
30
+ """Initialize from string.
31
+ Multiline strings are centered.
32
+ """
33
+ self.s = s
34
+ #picture is a string that just can be printed
35
+ self.picture = stringPict.equalLengths(s.splitlines())
36
+ #baseline is the line number of the "base line"
37
+ self.baseline = baseline
38
+ self.binding = None
39
+
40
+ @staticmethod
41
+ def equalLengths(lines):
42
+ # empty lines
43
+ if not lines:
44
+ return ['']
45
+
46
+ width = max(line_width(line) for line in lines)
47
+ return [center(line, width) for line in lines]
48
+
49
+ def height(self):
50
+ """The height of the picture in characters."""
51
+ return len(self.picture)
52
+
53
+ def width(self):
54
+ """The width of the picture in characters."""
55
+ return line_width(self.picture[0])
56
+
57
+ @staticmethod
58
+ def next(*args):
59
+ """Put a string of stringPicts next to each other.
60
+ Returns string, baseline arguments for stringPict.
61
+ """
62
+ #convert everything to stringPicts
63
+ objects = []
64
+ for arg in args:
65
+ if isinstance(arg, str):
66
+ arg = stringPict(arg)
67
+ objects.append(arg)
68
+
69
+ #make a list of pictures, with equal height and baseline
70
+ newBaseline = max(obj.baseline for obj in objects)
71
+ newHeightBelowBaseline = max(
72
+ obj.height() - obj.baseline
73
+ for obj in objects)
74
+ newHeight = newBaseline + newHeightBelowBaseline
75
+
76
+ pictures = []
77
+ for obj in objects:
78
+ oneEmptyLine = [' '*obj.width()]
79
+ basePadding = newBaseline - obj.baseline
80
+ totalPadding = newHeight - obj.height()
81
+ pictures.append(
82
+ oneEmptyLine * basePadding +
83
+ obj.picture +
84
+ oneEmptyLine * (totalPadding - basePadding))
85
+
86
+ result = [''.join(lines) for lines in zip(*pictures)]
87
+ return '\n'.join(result), newBaseline
88
+
89
+ def right(self, *args):
90
+ r"""Put pictures next to this one.
91
+ Returns string, baseline arguments for stringPict.
92
+ (Multiline) strings are allowed, and are given a baseline of 0.
93
+
94
+ Examples
95
+ ========
96
+
97
+ >>> from sympy.printing.pretty.stringpict import stringPict
98
+ >>> print(stringPict("10").right(" + ",stringPict("1\r-\r2",1))[0])
99
+ 1
100
+ 10 + -
101
+ 2
102
+
103
+ """
104
+ return stringPict.next(self, *args)
105
+
106
+ def left(self, *args):
107
+ """Put pictures (left to right) at left.
108
+ Returns string, baseline arguments for stringPict.
109
+ """
110
+ return stringPict.next(*(args + (self,)))
111
+
112
+ @staticmethod
113
+ def stack(*args):
114
+ """Put pictures on top of each other,
115
+ from top to bottom.
116
+ Returns string, baseline arguments for stringPict.
117
+ The baseline is the baseline of the second picture.
118
+ Everything is centered.
119
+ Baseline is the baseline of the second picture.
120
+ Strings are allowed.
121
+ The special value stringPict.LINE is a row of '-' extended to the width.
122
+ """
123
+ #convert everything to stringPicts; keep LINE
124
+ objects = []
125
+ for arg in args:
126
+ if arg is not stringPict.LINE and isinstance(arg, str):
127
+ arg = stringPict(arg)
128
+ objects.append(arg)
129
+
130
+ #compute new width
131
+ newWidth = max(
132
+ obj.width()
133
+ for obj in objects
134
+ if obj is not stringPict.LINE)
135
+
136
+ lineObj = stringPict(hobj('-', newWidth))
137
+
138
+ #replace LINE with proper lines
139
+ for i, obj in enumerate(objects):
140
+ if obj is stringPict.LINE:
141
+ objects[i] = lineObj
142
+
143
+ #stack the pictures, and center the result
144
+ newPicture = [center(line, newWidth) for obj in objects for line in obj.picture]
145
+ newBaseline = objects[0].height() + objects[1].baseline
146
+ return '\n'.join(newPicture), newBaseline
147
+
148
+ def below(self, *args):
149
+ """Put pictures under this picture.
150
+ Returns string, baseline arguments for stringPict.
151
+ Baseline is baseline of top picture
152
+
153
+ Examples
154
+ ========
155
+
156
+ >>> from sympy.printing.pretty.stringpict import stringPict
157
+ >>> print(stringPict("x+3").below(
158
+ ... stringPict.LINE, '3')[0]) #doctest: +NORMALIZE_WHITESPACE
159
+ x+3
160
+ ---
161
+ 3
162
+
163
+ """
164
+ s, baseline = stringPict.stack(self, *args)
165
+ return s, self.baseline
166
+
167
+ def above(self, *args):
168
+ """Put pictures above this picture.
169
+ Returns string, baseline arguments for stringPict.
170
+ Baseline is baseline of bottom picture.
171
+ """
172
+ string, baseline = stringPict.stack(*(args + (self,)))
173
+ baseline = len(string.splitlines()) - self.height() + self.baseline
174
+ return string, baseline
175
+
176
+ def parens(self, left='(', right=')', ifascii_nougly=False):
177
+ """Put parentheses around self.
178
+ Returns string, baseline arguments for stringPict.
179
+
180
+ left or right can be None or empty string which means 'no paren from
181
+ that side'
182
+ """
183
+ h = self.height()
184
+ b = self.baseline
185
+
186
+ # XXX this is a hack -- ascii parens are ugly!
187
+ if ifascii_nougly and not pretty_use_unicode():
188
+ h = 1
189
+ b = 0
190
+
191
+ res = self
192
+
193
+ if left:
194
+ lparen = stringPict(vobj(left, h), baseline=b)
195
+ res = stringPict(*lparen.right(self))
196
+ if right:
197
+ rparen = stringPict(vobj(right, h), baseline=b)
198
+ res = stringPict(*res.right(rparen))
199
+
200
+ return ('\n'.join(res.picture), res.baseline)
201
+
202
+ def leftslash(self):
203
+ """Precede object by a slash of the proper size.
204
+ """
205
+ # XXX not used anywhere ?
206
+ height = max(
207
+ self.baseline,
208
+ self.height() - 1 - self.baseline)*2 + 1
209
+ slash = '\n'.join(
210
+ ' '*(height - i - 1) + xobj('/', 1) + ' '*i
211
+ for i in range(height)
212
+ )
213
+ return self.left(stringPict(slash, height//2))
214
+
215
+ def root(self, n=None):
216
+ """Produce a nice root symbol.
217
+ Produces ugly results for big n inserts.
218
+ """
219
+ # XXX not used anywhere
220
+ # XXX duplicate of root drawing in pretty.py
221
+ #put line over expression
222
+ result = self.above('_'*self.width())
223
+ #construct right half of root symbol
224
+ height = self.height()
225
+ slash = '\n'.join(
226
+ ' ' * (height - i - 1) + '/' + ' ' * i
227
+ for i in range(height)
228
+ )
229
+ slash = stringPict(slash, height - 1)
230
+ #left half of root symbol
231
+ if height > 2:
232
+ downline = stringPict('\\ \n \\', 1)
233
+ else:
234
+ downline = stringPict('\\')
235
+ #put n on top, as low as possible
236
+ if n is not None and n.width() > downline.width():
237
+ downline = downline.left(' '*(n.width() - downline.width()))
238
+ downline = downline.above(n)
239
+ #build root symbol
240
+ root = downline.right(slash)
241
+ #glue it on at the proper height
242
+ #normally, the root symbel is as high as self
243
+ #which is one less than result
244
+ #this moves the root symbol one down
245
+ #if the root became higher, the baseline has to grow too
246
+ root.baseline = result.baseline - result.height() + root.height()
247
+ return result.left(root)
248
+
249
+ def render(self, * args, **kwargs):
250
+ """Return the string form of self.
251
+
252
+ Unless the argument line_break is set to False, it will
253
+ break the expression in a form that can be printed
254
+ on the terminal without being broken up.
255
+ """
256
+ if _GLOBAL_WRAP_LINE is not None:
257
+ kwargs["wrap_line"] = _GLOBAL_WRAP_LINE
258
+
259
+ if kwargs["wrap_line"] is False:
260
+ return "\n".join(self.picture)
261
+
262
+ if kwargs["num_columns"] is not None:
263
+ # Read the argument num_columns if it is not None
264
+ ncols = kwargs["num_columns"]
265
+ else:
266
+ # Attempt to get a terminal width
267
+ ncols = self.terminal_width()
268
+
269
+ if ncols <= 0:
270
+ ncols = 80
271
+
272
+ # If smaller than the terminal width, no need to correct
273
+ if self.width() <= ncols:
274
+ return type(self.picture[0])(self)
275
+
276
+ """
277
+ Break long-lines in a visually pleasing format.
278
+ without overflow indicators | with overflow indicators
279
+ | 2 2 3 | | 2 2 3 ↪|
280
+ |6*x *y + 4*x*y + | |6*x *y + 4*x*y + ↪|
281
+ | | | |
282
+ | 3 4 4 | |↪ 3 4 4 |
283
+ |4*y*x + x + y | |↪ 4*y*x + x + y |
284
+ |a*c*e + a*c*f + a*d | |a*c*e + a*c*f + a*d ↪|
285
+ |*e + a*d*f + b*c*e | | |
286
+ |+ b*c*f + b*d*e + b | |↪ *e + a*d*f + b*c* ↪|
287
+ |*d*f | | |
288
+ | | |↪ e + b*c*f + b*d*e ↪|
289
+ | | | |
290
+ | | |↪ + b*d*f |
291
+ """
292
+
293
+ overflow_first = ""
294
+ if kwargs["use_unicode"] or pretty_use_unicode():
295
+ overflow_start = "\N{RIGHTWARDS ARROW WITH HOOK} "
296
+ overflow_end = " \N{RIGHTWARDS ARROW WITH HOOK}"
297
+ else:
298
+ overflow_start = "> "
299
+ overflow_end = " >"
300
+
301
+ def chunks(line):
302
+ """Yields consecutive chunks of line_width ncols"""
303
+ prefix = overflow_first
304
+ width, start = line_width(prefix + overflow_end), 0
305
+ for i, x in enumerate(line):
306
+ wx = line_width(x)
307
+ # Only flush the screen when the current character overflows.
308
+ # This way, combining marks can be appended even when width == ncols.
309
+ if width + wx > ncols:
310
+ yield prefix + line[start:i] + overflow_end
311
+ prefix = overflow_start
312
+ width, start = line_width(prefix + overflow_end), i
313
+ width += wx
314
+ yield prefix + line[start:]
315
+
316
+ # Concurrently assemble chunks of all lines into individual screens
317
+ pictures = zip(*map(chunks, self.picture))
318
+
319
+ # Join lines of each screen into sub-pictures
320
+ pictures = ["\n".join(picture) for picture in pictures]
321
+
322
+ # Add spacers between sub-pictures
323
+ return "\n\n".join(pictures)
324
+
325
+ def terminal_width(self):
326
+ """Return the terminal width if possible, otherwise return 0.
327
+ """
328
+ size = shutil.get_terminal_size(fallback=(0, 0))
329
+ return size.columns
330
+
331
+ def __eq__(self, o):
332
+ if isinstance(o, str):
333
+ return '\n'.join(self.picture) == o
334
+ elif isinstance(o, stringPict):
335
+ return o.picture == self.picture
336
+ return False
337
+
338
+ def __hash__(self):
339
+ return super().__hash__()
340
+
341
+ def __str__(self):
342
+ return '\n'.join(self.picture)
343
+
344
+ def __repr__(self):
345
+ return "stringPict(%r,%d)" % ('\n'.join(self.picture), self.baseline)
346
+
347
+ def __getitem__(self, index):
348
+ return self.picture[index]
349
+
350
+ def __len__(self):
351
+ return len(self.s)
352
+
353
+
354
+ class prettyForm(stringPict):
355
+ """
356
+ Extension of the stringPict class that knows about basic math applications,
357
+ optimizing double minus signs.
358
+
359
+ "Binding" is interpreted as follows::
360
+
361
+ ATOM this is an atom: never needs to be parenthesized
362
+ FUNC this is a function application: parenthesize if added (?)
363
+ DIV this is a division: make wider division if divided
364
+ POW this is a power: only parenthesize if exponent
365
+ MUL this is a multiplication: parenthesize if powered
366
+ ADD this is an addition: parenthesize if multiplied or powered
367
+ NEG this is a negative number: optimize if added, parenthesize if
368
+ multiplied or powered
369
+ OPEN this is an open object: parenthesize if added, multiplied, or
370
+ powered (example: Piecewise)
371
+ """
372
+ ATOM, FUNC, DIV, POW, MUL, ADD, NEG, OPEN = range(8)
373
+
374
+ def __init__(self, s, baseline=0, binding=0, unicode=None):
375
+ """Initialize from stringPict and binding power."""
376
+ stringPict.__init__(self, s, baseline)
377
+ self.binding = binding
378
+ if unicode is not None:
379
+ sympy_deprecation_warning(
380
+ """
381
+ The unicode argument to prettyForm is deprecated. Only the s
382
+ argument (the first positional argument) should be passed.
383
+ """,
384
+ deprecated_since_version="1.7",
385
+ active_deprecations_target="deprecated-pretty-printing-functions")
386
+ self._unicode = unicode or s
387
+
388
+ @property
389
+ def unicode(self):
390
+ sympy_deprecation_warning(
391
+ """
392
+ The prettyForm.unicode attribute is deprecated. Use the
393
+ prettyForm.s attribute instead.
394
+ """,
395
+ deprecated_since_version="1.7",
396
+ active_deprecations_target="deprecated-pretty-printing-functions")
397
+ return self._unicode
398
+
399
+ # Note: code to handle subtraction is in _print_Add
400
+
401
+ def __add__(self, *others):
402
+ """Make a pretty addition.
403
+ Addition of negative numbers is simplified.
404
+ """
405
+ arg = self
406
+ if arg.binding > prettyForm.NEG:
407
+ arg = stringPict(*arg.parens())
408
+ result = [arg]
409
+ for arg in others:
410
+ #add parentheses for weak binders
411
+ if arg.binding > prettyForm.NEG:
412
+ arg = stringPict(*arg.parens())
413
+ #use existing minus sign if available
414
+ if arg.binding != prettyForm.NEG:
415
+ result.append(' + ')
416
+ result.append(arg)
417
+ return prettyForm(binding=prettyForm.ADD, *stringPict.next(*result))
418
+
419
+ def __truediv__(self, den, slashed=False):
420
+ """Make a pretty division; stacked or slashed.
421
+ """
422
+ if slashed:
423
+ raise NotImplementedError("Can't do slashed fraction yet")
424
+ num = self
425
+ if num.binding == prettyForm.DIV:
426
+ num = stringPict(*num.parens())
427
+ if den.binding == prettyForm.DIV:
428
+ den = stringPict(*den.parens())
429
+
430
+ if num.binding==prettyForm.NEG:
431
+ num = num.right(" ")[0]
432
+
433
+ return prettyForm(binding=prettyForm.DIV, *stringPict.stack(
434
+ num,
435
+ stringPict.LINE,
436
+ den))
437
+
438
+ def __mul__(self, *others):
439
+ """Make a pretty multiplication.
440
+ Parentheses are needed around +, - and neg.
441
+ """
442
+ quantity = {
443
+ 'degree': "\N{DEGREE SIGN}"
444
+ }
445
+
446
+ if len(others) == 0:
447
+ return self # We aren't actually multiplying... So nothing to do here.
448
+
449
+ # add parens on args that need them
450
+ arg = self
451
+ if arg.binding > prettyForm.MUL and arg.binding != prettyForm.NEG:
452
+ arg = stringPict(*arg.parens())
453
+ result = [arg]
454
+ for arg in others:
455
+ if arg.picture[0] not in quantity.values():
456
+ result.append(xsym('*'))
457
+ #add parentheses for weak binders
458
+ if arg.binding > prettyForm.MUL and arg.binding != prettyForm.NEG:
459
+ arg = stringPict(*arg.parens())
460
+ result.append(arg)
461
+
462
+ len_res = len(result)
463
+ for i in range(len_res):
464
+ if i < len_res - 1 and result[i] == '-1' and result[i + 1] == xsym('*'):
465
+ # substitute -1 by -, like in -1*x -> -x
466
+ result.pop(i)
467
+ result.pop(i)
468
+ result.insert(i, '-')
469
+ if result[0][0] == '-':
470
+ # if there is a - sign in front of all
471
+ # This test was failing to catch a prettyForm.__mul__(prettyForm("-1", 0, 6)) being negative
472
+ bin = prettyForm.NEG
473
+ if result[0] == '-':
474
+ right = result[1]
475
+ if right.picture[right.baseline][0] == '-':
476
+ result[0] = '- '
477
+ else:
478
+ bin = prettyForm.MUL
479
+ return prettyForm(binding=bin, *stringPict.next(*result))
480
+
481
+ def __repr__(self):
482
+ return "prettyForm(%r,%d,%d)" % (
483
+ '\n'.join(self.picture),
484
+ self.baseline,
485
+ self.binding)
486
+
487
+ def __pow__(self, b):
488
+ """Make a pretty power.
489
+ """
490
+ a = self
491
+ use_inline_func_form = False
492
+ if b.binding == prettyForm.POW:
493
+ b = stringPict(*b.parens())
494
+ if a.binding > prettyForm.FUNC:
495
+ a = stringPict(*a.parens())
496
+ elif a.binding == prettyForm.FUNC:
497
+ # heuristic for when to use inline power
498
+ if b.height() > 1:
499
+ a = stringPict(*a.parens())
500
+ else:
501
+ use_inline_func_form = True
502
+
503
+ if use_inline_func_form:
504
+ # 2
505
+ # sin + + (x)
506
+ b.baseline = a.prettyFunc.baseline + b.height()
507
+ func = stringPict(*a.prettyFunc.right(b))
508
+ return prettyForm(*func.right(a.prettyArgs))
509
+ else:
510
+ # 2 <-- top
511
+ # (x+y) <-- bot
512
+ top = stringPict(*b.left(' '*a.width()))
513
+ bot = stringPict(*a.right(' '*b.width()))
514
+
515
+ return prettyForm(binding=prettyForm.POW, *bot.above(top))
516
+
517
+ simpleFunctions = ["sin", "cos", "tan"]
518
+
519
+ @staticmethod
520
+ def apply(function, *args):
521
+ """Functions of one or more variables.
522
+ """
523
+ if function in prettyForm.simpleFunctions:
524
+ #simple function: use only space if possible
525
+ assert len(
526
+ args) == 1, "Simple function %s must have 1 argument" % function
527
+ arg = args[0].__pretty__()
528
+ if arg.binding <= prettyForm.DIV:
529
+ #optimization: no parentheses necessary
530
+ return prettyForm(binding=prettyForm.FUNC, *arg.left(function + ' '))
531
+ argumentList = []
532
+ for arg in args:
533
+ argumentList.append(',')
534
+ argumentList.append(arg.__pretty__())
535
+ argumentList = stringPict(*stringPict.next(*argumentList[1:]))
536
+ argumentList = stringPict(*argumentList.parens())
537
+ return prettyForm(binding=prettyForm.ATOM, *argumentList.left(function))
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (199 Bytes). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_aesaracode.cpython-312.pyc ADDED
Binary file (37.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_c.cpython-312.pyc ADDED
Binary file (54.9 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_codeprinter.cpython-312.pyc ADDED
Binary file (3.19 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_conventions.cpython-312.pyc ADDED
Binary file (7.16 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_cupy.cpython-312.pyc ADDED
Binary file (4.18 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_cxx.cpython-312.pyc ADDED
Binary file (7.06 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_dot.cpython-312.pyc ADDED
Binary file (9.11 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_fortran.cpython-312.pyc ADDED
Binary file (52.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_glsl.cpython-312.pyc ADDED
Binary file (39.8 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_gtk.cpython-312.pyc ADDED
Binary file (1.1 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_jax.cpython-312.pyc ADDED
Binary file (22.2 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_jscode.cpython-312.pyc ADDED
Binary file (20.6 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_julia.cpython-312.pyc ADDED
Binary file (26.1 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_lambdarepr.cpython-312.pyc ADDED
Binary file (11.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_llvmjit.cpython-312.pyc ADDED
Binary file (12.5 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_maple.cpython-312.pyc ADDED
Binary file (25.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_mathematica.cpython-312.pyc ADDED
Binary file (19.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_numpy.cpython-312.pyc ADDED
Binary file (21.6 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_octave.cpython-312.pyc ADDED
Binary file (37.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_precedence.cpython-312.pyc ADDED
Binary file (6.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_preview.cpython-312.pyc ADDED
Binary file (1.57 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_pycode.cpython-312.pyc ADDED
Binary file (29.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_python.cpython-312.pyc ADDED
Binary file (13.1 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_rcode.cpython-312.pyc ADDED
Binary file (25.3 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_repr.cpython-312.pyc ADDED
Binary file (24.2 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_rust.cpython-312.pyc ADDED
Binary file (21.8 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_smtlib.cpython-312.pyc ADDED
Binary file (32.4 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_str.cpython-312.pyc ADDED
Binary file (88.2 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_tableform.cpython-312.pyc ADDED
Binary file (6.92 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_tensorflow.cpython-312.pyc ADDED
Binary file (28.6 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_theanocode.cpython-312.pyc ADDED
Binary file (38.9 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/__pycache__/test_tree.cpython-312.pyc ADDED
Binary file (4.73 kB). View file
 
lib/python3.12/site-packages/sympy/printing/tests/test_conventions.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from sympy.core.function import (Derivative, Function)
4
+ from sympy.core.numbers import oo
5
+ from sympy.core.symbol import symbols
6
+ from sympy.functions.elementary.exponential import exp
7
+ from sympy.functions.elementary.trigonometric import cos
8
+ from sympy.integrals.integrals import Integral
9
+ from sympy.functions.special.bessel import besselj
10
+ from sympy.functions.special.polynomials import legendre
11
+ from sympy.functions.combinatorial.numbers import bell
12
+ from sympy.printing.conventions import split_super_sub, requires_partial
13
+ from sympy.testing.pytest import XFAIL
14
+
15
+ def test_super_sub():
16
+ assert split_super_sub("beta_13_2") == ("beta", [], ["13", "2"])
17
+ assert split_super_sub("beta_132_20") == ("beta", [], ["132", "20"])
18
+ assert split_super_sub("beta_13") == ("beta", [], ["13"])
19
+ assert split_super_sub("x_a_b") == ("x", [], ["a", "b"])
20
+ assert split_super_sub("x_1_2_3") == ("x", [], ["1", "2", "3"])
21
+ assert split_super_sub("x_a_b1") == ("x", [], ["a", "b1"])
22
+ assert split_super_sub("x_a_1") == ("x", [], ["a", "1"])
23
+ assert split_super_sub("x_1_a") == ("x", [], ["1", "a"])
24
+ assert split_super_sub("x_1^aa") == ("x", ["aa"], ["1"])
25
+ assert split_super_sub("x_1__aa") == ("x", ["aa"], ["1"])
26
+ assert split_super_sub("x_11^a") == ("x", ["a"], ["11"])
27
+ assert split_super_sub("x_11__a") == ("x", ["a"], ["11"])
28
+ assert split_super_sub("x_a_b_c_d") == ("x", [], ["a", "b", "c", "d"])
29
+ assert split_super_sub("x_a_b^c^d") == ("x", ["c", "d"], ["a", "b"])
30
+ assert split_super_sub("x_a_b__c__d") == ("x", ["c", "d"], ["a", "b"])
31
+ assert split_super_sub("x_a^b_c^d") == ("x", ["b", "d"], ["a", "c"])
32
+ assert split_super_sub("x_a__b_c__d") == ("x", ["b", "d"], ["a", "c"])
33
+ assert split_super_sub("x^a^b_c_d") == ("x", ["a", "b"], ["c", "d"])
34
+ assert split_super_sub("x__a__b_c_d") == ("x", ["a", "b"], ["c", "d"])
35
+ assert split_super_sub("x^a^b^c^d") == ("x", ["a", "b", "c", "d"], [])
36
+ assert split_super_sub("x__a__b__c__d") == ("x", ["a", "b", "c", "d"], [])
37
+ assert split_super_sub("alpha_11") == ("alpha", [], ["11"])
38
+ assert split_super_sub("alpha_11_11") == ("alpha", [], ["11", "11"])
39
+ assert split_super_sub("w1") == ("w", [], ["1"])
40
+ assert split_super_sub("w𝟙") == ("w", [], ["𝟙"])
41
+ assert split_super_sub("w11") == ("w", [], ["11"])
42
+ assert split_super_sub("w𝟙𝟙") == ("w", [], ["𝟙𝟙"])
43
+ assert split_super_sub("w𝟙2𝟙") == ("w", [], ["𝟙2𝟙"])
44
+ assert split_super_sub("w1^a") == ("w", ["a"], ["1"])
45
+ assert split_super_sub("ω1") == ("ω", [], ["1"])
46
+ assert split_super_sub("ω11") == ("ω", [], ["11"])
47
+ assert split_super_sub("ω1^a") == ("ω", ["a"], ["1"])
48
+ assert split_super_sub("ω𝟙^α") == ("ω", ["α"], ["𝟙"])
49
+ assert split_super_sub("ω𝟙2^3α") == ("ω", ["3α"], ["𝟙2"])
50
+ assert split_super_sub("") == ("", [], [])
51
+
52
+
53
+ def test_requires_partial():
54
+ x, y, z, t, nu = symbols('x y z t nu')
55
+ n = symbols('n', integer=True)
56
+
57
+ f = x * y
58
+ assert requires_partial(Derivative(f, x)) is True
59
+ assert requires_partial(Derivative(f, y)) is True
60
+
61
+ ## integrating out one of the variables
62
+ assert requires_partial(Derivative(Integral(exp(-x * y), (x, 0, oo)), y, evaluate=False)) is False
63
+
64
+ ## bessel function with smooth parameter
65
+ f = besselj(nu, x)
66
+ assert requires_partial(Derivative(f, x)) is True
67
+ assert requires_partial(Derivative(f, nu)) is True
68
+
69
+ ## bessel function with integer parameter
70
+ f = besselj(n, x)
71
+ assert requires_partial(Derivative(f, x)) is False
72
+ # this is not really valid (differentiating with respect to an integer)
73
+ # but there's no reason to use the partial derivative symbol there. make
74
+ # sure we don't throw an exception here, though
75
+ assert requires_partial(Derivative(f, n)) is False
76
+
77
+ ## bell polynomial
78
+ f = bell(n, x)
79
+ assert requires_partial(Derivative(f, x)) is False
80
+ # again, invalid
81
+ assert requires_partial(Derivative(f, n)) is False
82
+
83
+ ## legendre polynomial
84
+ f = legendre(0, x)
85
+ assert requires_partial(Derivative(f, x)) is False
86
+
87
+ f = legendre(n, x)
88
+ assert requires_partial(Derivative(f, x)) is False
89
+ # again, invalid
90
+ assert requires_partial(Derivative(f, n)) is False
91
+
92
+ f = x ** n
93
+ assert requires_partial(Derivative(f, x)) is False
94
+
95
+ assert requires_partial(Derivative(Integral((x*y) ** n * exp(-x * y), (x, 0, oo)), y, evaluate=False)) is False
96
+
97
+ # parametric equation
98
+ f = (exp(t), cos(t))
99
+ g = sum(f)
100
+ assert requires_partial(Derivative(g, t)) is False
101
+
102
+ f = symbols('f', cls=Function)
103
+ assert requires_partial(Derivative(f(x), x)) is False
104
+ assert requires_partial(Derivative(f(x), y)) is False
105
+ assert requires_partial(Derivative(f(x, y), x)) is True
106
+ assert requires_partial(Derivative(f(x, y), y)) is True
107
+ assert requires_partial(Derivative(f(x, y), z)) is True
108
+ assert requires_partial(Derivative(f(x, y), x, y)) is True
109
+
110
+ @XFAIL
111
+ def test_requires_partial_unspecified_variables():
112
+ x, y = symbols('x y')
113
+ # function of unspecified variables
114
+ f = symbols('f', cls=Function)
115
+ assert requires_partial(Derivative(f, x)) is False
116
+ assert requires_partial(Derivative(f, x, y)) is True
lib/python3.12/site-packages/sympy/printing/tests/test_gtk.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.functions.elementary.trigonometric import sin
2
+ from sympy.printing.gtk import print_gtk
3
+ from sympy.testing.pytest import XFAIL, raises
4
+
5
+ # this test fails if python-lxml isn't installed. We don't want to depend on
6
+ # anything with SymPy
7
+
8
+
9
+ @XFAIL
10
+ def test_1():
11
+ from sympy.abc import x
12
+ print_gtk(x**2, start_viewer=False)
13
+ print_gtk(x**2 + sin(x)/4, start_viewer=False)
14
+
15
+
16
+ def test_settings():
17
+ from sympy.abc import x
18
+ raises(TypeError, lambda: print_gtk(x, method="garbage"))
lib/python3.12/site-packages/sympy/printing/tests/test_jax.py ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.concrete.summations import Sum
2
+ from sympy.core.mod import Mod
3
+ from sympy.core.relational import (Equality, Unequality)
4
+ from sympy.functions.elementary.miscellaneous import sqrt
5
+ from sympy.functions.elementary.piecewise import Piecewise
6
+ from sympy.matrices.expressions.blockmatrix import BlockMatrix
7
+ from sympy.matrices.expressions.matexpr import MatrixSymbol
8
+ from sympy.matrices.expressions.special import Identity
9
+ from sympy.utilities.lambdify import lambdify
10
+
11
+ from sympy.abc import x, i, j, a, b, c, d
12
+ from sympy.core import Function, Pow, Symbol
13
+ from sympy.codegen.matrix_nodes import MatrixSolve
14
+ from sympy.codegen.numpy_nodes import logaddexp, logaddexp2
15
+ from sympy.codegen.cfunctions import log1p, expm1, hypot, log10, exp2, log2, Sqrt
16
+ from sympy.tensor.array import Array
17
+ from sympy.tensor.array.expressions.array_expressions import ArrayTensorProduct, ArrayAdd, \
18
+ PermuteDims, ArrayDiagonal
19
+ from sympy.printing.numpy import JaxPrinter, _jax_known_constants, _jax_known_functions
20
+ from sympy.tensor.array.expressions.from_matrix_to_array import convert_matrix_to_array
21
+
22
+ from sympy.testing.pytest import skip, raises
23
+ from sympy.external import import_module
24
+
25
+ # Unlike NumPy which will aggressively promote operands to double precision,
26
+ # jax always uses single precision. Double precision in jax can be
27
+ # configured before the call to `import jax`, however this must be explicitly
28
+ # configured and is not fully supported. Thus, the tests here have been modified
29
+ # from the tests in test_numpy.py, only in the fact that they assert lambdify
30
+ # function accuracy to only single precision accuracy.
31
+ # https://jax.readthedocs.io/en/latest/notebooks/Common_Gotchas_in_JAX.html#double-64bit-precision
32
+
33
+ jax = import_module('jax')
34
+
35
+ if jax:
36
+ deafult_float_info = jax.numpy.finfo(jax.numpy.array([]).dtype)
37
+ JAX_DEFAULT_EPSILON = deafult_float_info.eps
38
+
39
+
40
+ def test_jax_piecewise_regression():
41
+ """
42
+ NumPyPrinter needs to print Piecewise()'s choicelist as a list to avoid
43
+ breaking compatibility with numpy 1.8. This is not necessary in numpy 1.9+.
44
+ See gh-9747 and gh-9749 for details.
45
+ """
46
+ printer = JaxPrinter()
47
+ p = Piecewise((1, x < 0), (0, True))
48
+ assert printer.doprint(p) == \
49
+ 'jax.numpy.select([jax.numpy.less(x, 0),True], [1,0], default=jax.numpy.nan)'
50
+ assert printer.module_imports == {'jax.numpy': {'select', 'less', 'nan'}}
51
+
52
+
53
+ def test_jax_logaddexp():
54
+ lae = logaddexp(a, b)
55
+ assert JaxPrinter().doprint(lae) == 'jax.numpy.logaddexp(a, b)'
56
+ lae2 = logaddexp2(a, b)
57
+ assert JaxPrinter().doprint(lae2) == 'jax.numpy.logaddexp2(a, b)'
58
+
59
+
60
+ def test_jax_sum():
61
+ if not jax:
62
+ skip("JAX not installed")
63
+
64
+ s = Sum(x ** i, (i, a, b))
65
+ f = lambdify((a, b, x), s, 'jax')
66
+
67
+ a_, b_ = 0, 10
68
+ x_ = jax.numpy.linspace(-1, +1, 10)
69
+ assert jax.numpy.allclose(f(a_, b_, x_), sum(x_ ** i_ for i_ in range(a_, b_ + 1)))
70
+
71
+ s = Sum(i * x, (i, a, b))
72
+ f = lambdify((a, b, x), s, 'jax')
73
+
74
+ a_, b_ = 0, 10
75
+ x_ = jax.numpy.linspace(-1, +1, 10)
76
+ assert jax.numpy.allclose(f(a_, b_, x_), sum(i_ * x_ for i_ in range(a_, b_ + 1)))
77
+
78
+
79
+ def test_jax_multiple_sums():
80
+ if not jax:
81
+ skip("JAX not installed")
82
+
83
+ s = Sum((x + j) * i, (i, a, b), (j, c, d))
84
+ f = lambdify((a, b, c, d, x), s, 'jax')
85
+
86
+ a_, b_ = 0, 10
87
+ c_, d_ = 11, 21
88
+ x_ = jax.numpy.linspace(-1, +1, 10)
89
+ assert jax.numpy.allclose(f(a_, b_, c_, d_, x_),
90
+ sum((x_ + j_) * i_ for i_ in range(a_, b_ + 1) for j_ in range(c_, d_ + 1)))
91
+
92
+
93
+ def test_jax_codegen_einsum():
94
+ if not jax:
95
+ skip("JAX not installed")
96
+
97
+ M = MatrixSymbol("M", 2, 2)
98
+ N = MatrixSymbol("N", 2, 2)
99
+
100
+ cg = convert_matrix_to_array(M * N)
101
+ f = lambdify((M, N), cg, 'jax')
102
+
103
+ ma = jax.numpy.array([[1, 2], [3, 4]])
104
+ mb = jax.numpy.array([[1,-2], [-1, 3]])
105
+ assert (f(ma, mb) == jax.numpy.matmul(ma, mb)).all()
106
+
107
+
108
+ def test_jax_codegen_extra():
109
+ if not jax:
110
+ skip("JAX not installed")
111
+
112
+ M = MatrixSymbol("M", 2, 2)
113
+ N = MatrixSymbol("N", 2, 2)
114
+ P = MatrixSymbol("P", 2, 2)
115
+ Q = MatrixSymbol("Q", 2, 2)
116
+ ma = jax.numpy.array([[1, 2], [3, 4]])
117
+ mb = jax.numpy.array([[1,-2], [-1, 3]])
118
+ mc = jax.numpy.array([[2, 0], [1, 2]])
119
+ md = jax.numpy.array([[1,-1], [4, 7]])
120
+
121
+ cg = ArrayTensorProduct(M, N)
122
+ f = lambdify((M, N), cg, 'jax')
123
+ assert (f(ma, mb) == jax.numpy.einsum(ma, [0, 1], mb, [2, 3])).all()
124
+
125
+ cg = ArrayAdd(M, N)
126
+ f = lambdify((M, N), cg, 'jax')
127
+ assert (f(ma, mb) == ma+mb).all()
128
+
129
+ cg = ArrayAdd(M, N, P)
130
+ f = lambdify((M, N, P), cg, 'jax')
131
+ assert (f(ma, mb, mc) == ma+mb+mc).all()
132
+
133
+ cg = ArrayAdd(M, N, P, Q)
134
+ f = lambdify((M, N, P, Q), cg, 'jax')
135
+ assert (f(ma, mb, mc, md) == ma+mb+mc+md).all()
136
+
137
+ cg = PermuteDims(M, [1, 0])
138
+ f = lambdify((M,), cg, 'jax')
139
+ assert (f(ma) == ma.T).all()
140
+
141
+ cg = PermuteDims(ArrayTensorProduct(M, N), [1, 2, 3, 0])
142
+ f = lambdify((M, N), cg, 'jax')
143
+ assert (f(ma, mb) == jax.numpy.transpose(jax.numpy.einsum(ma, [0, 1], mb, [2, 3]), (1, 2, 3, 0))).all()
144
+
145
+ cg = ArrayDiagonal(ArrayTensorProduct(M, N), (1, 2))
146
+ f = lambdify((M, N), cg, 'jax')
147
+ assert (f(ma, mb) == jax.numpy.diagonal(jax.numpy.einsum(ma, [0, 1], mb, [2, 3]), axis1=1, axis2=2)).all()
148
+
149
+
150
+ def test_jax_relational():
151
+ if not jax:
152
+ skip("JAX not installed")
153
+
154
+ e = Equality(x, 1)
155
+
156
+ f = lambdify((x,), e, 'jax')
157
+ x_ = jax.numpy.array([0, 1, 2])
158
+ assert jax.numpy.array_equal(f(x_), [False, True, False])
159
+
160
+ e = Unequality(x, 1)
161
+
162
+ f = lambdify((x,), e, 'jax')
163
+ x_ = jax.numpy.array([0, 1, 2])
164
+ assert jax.numpy.array_equal(f(x_), [True, False, True])
165
+
166
+ e = (x < 1)
167
+
168
+ f = lambdify((x,), e, 'jax')
169
+ x_ = jax.numpy.array([0, 1, 2])
170
+ assert jax.numpy.array_equal(f(x_), [True, False, False])
171
+
172
+ e = (x <= 1)
173
+
174
+ f = lambdify((x,), e, 'jax')
175
+ x_ = jax.numpy.array([0, 1, 2])
176
+ assert jax.numpy.array_equal(f(x_), [True, True, False])
177
+
178
+ e = (x > 1)
179
+
180
+ f = lambdify((x,), e, 'jax')
181
+ x_ = jax.numpy.array([0, 1, 2])
182
+ assert jax.numpy.array_equal(f(x_), [False, False, True])
183
+
184
+ e = (x >= 1)
185
+
186
+ f = lambdify((x,), e, 'jax')
187
+ x_ = jax.numpy.array([0, 1, 2])
188
+ assert jax.numpy.array_equal(f(x_), [False, True, True])
189
+
190
+ # Multi-condition expressions
191
+ e = (x >= 1) & (x < 2)
192
+ f = lambdify((x,), e, 'jax')
193
+ x_ = jax.numpy.array([0, 1, 2])
194
+ assert jax.numpy.array_equal(f(x_), [False, True, False])
195
+
196
+ e = (x >= 1) | (x < 2)
197
+ f = lambdify((x,), e, 'jax')
198
+ x_ = jax.numpy.array([0, 1, 2])
199
+ assert jax.numpy.array_equal(f(x_), [True, True, True])
200
+
201
+ def test_jax_mod():
202
+ if not jax:
203
+ skip("JAX not installed")
204
+
205
+ e = Mod(a, b)
206
+ f = lambdify((a, b), e, 'jax')
207
+
208
+ a_ = jax.numpy.array([0, 1, 2, 3])
209
+ b_ = 2
210
+ assert jax.numpy.array_equal(f(a_, b_), [0, 1, 0, 1])
211
+
212
+ a_ = jax.numpy.array([0, 1, 2, 3])
213
+ b_ = jax.numpy.array([2, 2, 2, 2])
214
+ assert jax.numpy.array_equal(f(a_, b_), [0, 1, 0, 1])
215
+
216
+ a_ = jax.numpy.array([2, 3, 4, 5])
217
+ b_ = jax.numpy.array([2, 3, 4, 5])
218
+ assert jax.numpy.array_equal(f(a_, b_), [0, 0, 0, 0])
219
+
220
+
221
+ def test_jax_pow():
222
+ if not jax:
223
+ skip('JAX not installed')
224
+
225
+ expr = Pow(2, -1, evaluate=False)
226
+ f = lambdify([], expr, 'jax')
227
+ assert f() == 0.5
228
+
229
+
230
+ def test_jax_expm1():
231
+ if not jax:
232
+ skip("JAX not installed")
233
+
234
+ f = lambdify((a,), expm1(a), 'jax')
235
+ assert abs(f(1e-10) - 1e-10 - 5e-21) <= 1e-10 * JAX_DEFAULT_EPSILON
236
+
237
+
238
+ def test_jax_log1p():
239
+ if not jax:
240
+ skip("JAX not installed")
241
+
242
+ f = lambdify((a,), log1p(a), 'jax')
243
+ assert abs(f(1e-99) - 1e-99) <= 1e-99 * JAX_DEFAULT_EPSILON
244
+
245
+ def test_jax_hypot():
246
+ if not jax:
247
+ skip("JAX not installed")
248
+ assert abs(lambdify((a, b), hypot(a, b), 'jax')(3, 4) - 5) <= JAX_DEFAULT_EPSILON
249
+
250
+ def test_jax_log10():
251
+ if not jax:
252
+ skip("JAX not installed")
253
+
254
+ assert abs(lambdify((a,), log10(a), 'jax')(100) - 2) <= JAX_DEFAULT_EPSILON
255
+
256
+
257
+ def test_jax_exp2():
258
+ if not jax:
259
+ skip("JAX not installed")
260
+ assert abs(lambdify((a,), exp2(a), 'jax')(5) - 32) <= JAX_DEFAULT_EPSILON
261
+
262
+
263
+ def test_jax_log2():
264
+ if not jax:
265
+ skip("JAX not installed")
266
+ assert abs(lambdify((a,), log2(a), 'jax')(256) - 8) <= JAX_DEFAULT_EPSILON
267
+
268
+
269
+ def test_jax_Sqrt():
270
+ if not jax:
271
+ skip("JAX not installed")
272
+ assert abs(lambdify((a,), Sqrt(a), 'jax')(4) - 2) <= JAX_DEFAULT_EPSILON
273
+
274
+
275
+ def test_jax_sqrt():
276
+ if not jax:
277
+ skip("JAX not installed")
278
+ assert abs(lambdify((a,), sqrt(a), 'jax')(4) - 2) <= JAX_DEFAULT_EPSILON
279
+
280
+
281
+ def test_jax_matsolve():
282
+ if not jax:
283
+ skip("JAX not installed")
284
+
285
+ M = MatrixSymbol("M", 3, 3)
286
+ x = MatrixSymbol("x", 3, 1)
287
+
288
+ expr = M**(-1) * x + x
289
+ matsolve_expr = MatrixSolve(M, x) + x
290
+
291
+ f = lambdify((M, x), expr, 'jax')
292
+ f_matsolve = lambdify((M, x), matsolve_expr, 'jax')
293
+
294
+ m0 = jax.numpy.array([[1, 2, 3], [3, 2, 5], [5, 6, 7]])
295
+ assert jax.numpy.linalg.matrix_rank(m0) == 3
296
+
297
+ x0 = jax.numpy.array([3, 4, 5])
298
+
299
+ assert jax.numpy.allclose(f_matsolve(m0, x0), f(m0, x0))
300
+
301
+
302
+ def test_16857():
303
+ if not jax:
304
+ skip("JAX not installed")
305
+
306
+ a_1 = MatrixSymbol('a_1', 10, 3)
307
+ a_2 = MatrixSymbol('a_2', 10, 3)
308
+ a_3 = MatrixSymbol('a_3', 10, 3)
309
+ a_4 = MatrixSymbol('a_4', 10, 3)
310
+ A = BlockMatrix([[a_1, a_2], [a_3, a_4]])
311
+ assert A.shape == (20, 6)
312
+
313
+ printer = JaxPrinter()
314
+ assert printer.doprint(A) == 'jax.numpy.block([[a_1, a_2], [a_3, a_4]])'
315
+
316
+
317
+ def test_issue_17006():
318
+ if not jax:
319
+ skip("JAX not installed")
320
+
321
+ M = MatrixSymbol("M", 2, 2)
322
+
323
+ f = lambdify(M, M + Identity(2), 'jax')
324
+ ma = jax.numpy.array([[1, 2], [3, 4]])
325
+ mr = jax.numpy.array([[2, 2], [3, 5]])
326
+
327
+ assert (f(ma) == mr).all()
328
+
329
+ from sympy.core.symbol import symbols
330
+ n = symbols('n', integer=True)
331
+ N = MatrixSymbol("M", n, n)
332
+ raises(NotImplementedError, lambda: lambdify(N, N + Identity(n), 'jax'))
333
+
334
+
335
+ def test_jax_array():
336
+ assert JaxPrinter().doprint(Array(((1, 2), (3, 5)))) == 'jax.numpy.array([[1, 2], [3, 5]])'
337
+ assert JaxPrinter().doprint(Array((1, 2))) == 'jax.numpy.array((1, 2))'
338
+
339
+
340
+ def test_jax_known_funcs_consts():
341
+ assert _jax_known_constants['NaN'] == 'jax.numpy.nan'
342
+ assert _jax_known_constants['EulerGamma'] == 'jax.numpy.euler_gamma'
343
+
344
+ assert _jax_known_functions['acos'] == 'jax.numpy.arccos'
345
+ assert _jax_known_functions['log'] == 'jax.numpy.log'
346
+
347
+
348
+ def test_jax_print_methods():
349
+ prntr = JaxPrinter()
350
+ assert hasattr(prntr, '_print_acos')
351
+ assert hasattr(prntr, '_print_log')
352
+
353
+
354
+ def test_jax_printmethod():
355
+ printer = JaxPrinter()
356
+ assert hasattr(printer, 'printmethod')
357
+ assert printer.printmethod == '_jaxcode'
358
+
359
+
360
+ def test_jax_custom_print_method():
361
+
362
+ class expm1(Function):
363
+
364
+ def _jaxcode(self, printer):
365
+ x, = self.args
366
+ function = f'expm1({printer._print(x)})'
367
+ return printer._module_format(printer._module + '.' + function)
368
+
369
+ printer = JaxPrinter()
370
+ assert printer.doprint(expm1(Symbol('x'))) == 'jax.numpy.expm1(x)'
lib/python3.12/site-packages/sympy/printing/tests/test_jscode.py ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.core import (pi, oo, symbols, Rational, Integer, GoldenRatio,
2
+ EulerGamma, Catalan, Lambda, Dummy, S, Eq, Ne, Le,
3
+ Lt, Gt, Ge, Mod)
4
+ from sympy.functions import (Piecewise, sin, cos, Abs, exp, ceiling, sqrt,
5
+ sinh, cosh, tanh, asin, acos, acosh, Max, Min)
6
+ from sympy.testing.pytest import raises
7
+ from sympy.printing.jscode import JavascriptCodePrinter
8
+ from sympy.utilities.lambdify import implemented_function
9
+ from sympy.tensor import IndexedBase, Idx
10
+ from sympy.matrices import Matrix, MatrixSymbol
11
+
12
+ from sympy.printing.jscode import jscode
13
+
14
+ x, y, z = symbols('x,y,z')
15
+
16
+
17
+ def test_printmethod():
18
+ assert jscode(Abs(x)) == "Math.abs(x)"
19
+
20
+
21
+ def test_jscode_sqrt():
22
+ assert jscode(sqrt(x)) == "Math.sqrt(x)"
23
+ assert jscode(x**0.5) == "Math.sqrt(x)"
24
+ assert jscode(x**(S.One/3)) == "Math.cbrt(x)"
25
+
26
+
27
+ def test_jscode_Pow():
28
+ g = implemented_function('g', Lambda(x, 2*x))
29
+ assert jscode(x**3) == "Math.pow(x, 3)"
30
+ assert jscode(x**(y**3)) == "Math.pow(x, Math.pow(y, 3))"
31
+ assert jscode(1/(g(x)*3.5)**(x - y**x)/(x**2 + y)) == \
32
+ "Math.pow(3.5*2*x, -x + Math.pow(y, x))/(Math.pow(x, 2) + y)"
33
+ assert jscode(x**-1.0) == '1/x'
34
+
35
+
36
+ def test_jscode_constants_mathh():
37
+ assert jscode(exp(1)) == "Math.E"
38
+ assert jscode(pi) == "Math.PI"
39
+ assert jscode(oo) == "Number.POSITIVE_INFINITY"
40
+ assert jscode(-oo) == "Number.NEGATIVE_INFINITY"
41
+
42
+
43
+ def test_jscode_constants_other():
44
+ assert jscode(
45
+ 2*GoldenRatio) == "var GoldenRatio = %s;\n2*GoldenRatio" % GoldenRatio.evalf(17)
46
+ assert jscode(2*Catalan) == "var Catalan = %s;\n2*Catalan" % Catalan.evalf(17)
47
+ assert jscode(
48
+ 2*EulerGamma) == "var EulerGamma = %s;\n2*EulerGamma" % EulerGamma.evalf(17)
49
+
50
+
51
+ def test_jscode_Rational():
52
+ assert jscode(Rational(3, 7)) == "3/7"
53
+ assert jscode(Rational(18, 9)) == "2"
54
+ assert jscode(Rational(3, -7)) == "-3/7"
55
+ assert jscode(Rational(-3, -7)) == "3/7"
56
+
57
+
58
+ def test_Relational():
59
+ assert jscode(Eq(x, y)) == "x == y"
60
+ assert jscode(Ne(x, y)) == "x != y"
61
+ assert jscode(Le(x, y)) == "x <= y"
62
+ assert jscode(Lt(x, y)) == "x < y"
63
+ assert jscode(Gt(x, y)) == "x > y"
64
+ assert jscode(Ge(x, y)) == "x >= y"
65
+
66
+
67
+ def test_Mod():
68
+ assert jscode(Mod(x, y)) == '((x % y) + y) % y'
69
+ assert jscode(Mod(x, x + y)) == '((x % (x + y)) + (x + y)) % (x + y)'
70
+ p1, p2 = symbols('p1 p2', positive=True)
71
+ assert jscode(Mod(p1, p2)) == 'p1 % p2'
72
+ assert jscode(Mod(p1, p2 + 3)) == 'p1 % (p2 + 3)'
73
+ assert jscode(Mod(-3, -7, evaluate=False)) == '(-3) % (-7)'
74
+ assert jscode(-Mod(p1, p2)) == '-(p1 % p2)'
75
+ assert jscode(x*Mod(p1, p2)) == 'x*(p1 % p2)'
76
+
77
+
78
+ def test_jscode_Integer():
79
+ assert jscode(Integer(67)) == "67"
80
+ assert jscode(Integer(-1)) == "-1"
81
+
82
+
83
+ def test_jscode_functions():
84
+ assert jscode(sin(x) ** cos(x)) == "Math.pow(Math.sin(x), Math.cos(x))"
85
+ assert jscode(sinh(x) * cosh(x)) == "Math.sinh(x)*Math.cosh(x)"
86
+ assert jscode(Max(x, y) + Min(x, y)) == "Math.max(x, y) + Math.min(x, y)"
87
+ assert jscode(tanh(x)*acosh(y)) == "Math.tanh(x)*Math.acosh(y)"
88
+ assert jscode(asin(x)-acos(y)) == "-Math.acos(y) + Math.asin(x)"
89
+
90
+
91
+ def test_jscode_inline_function():
92
+ x = symbols('x')
93
+ g = implemented_function('g', Lambda(x, 2*x))
94
+ assert jscode(g(x)) == "2*x"
95
+ g = implemented_function('g', Lambda(x, 2*x/Catalan))
96
+ assert jscode(g(x)) == "var Catalan = %s;\n2*x/Catalan" % Catalan.evalf(17)
97
+ A = IndexedBase('A')
98
+ i = Idx('i', symbols('n', integer=True))
99
+ g = implemented_function('g', Lambda(x, x*(1 + x)*(2 + x)))
100
+ assert jscode(g(A[i]), assign_to=A[i]) == (
101
+ "for (var i=0; i<n; i++){\n"
102
+ " A[i] = (A[i] + 1)*(A[i] + 2)*A[i];\n"
103
+ "}"
104
+ )
105
+
106
+
107
+ def test_jscode_exceptions():
108
+ assert jscode(ceiling(x)) == "Math.ceil(x)"
109
+ assert jscode(Abs(x)) == "Math.abs(x)"
110
+
111
+
112
+ def test_jscode_boolean():
113
+ assert jscode(x & y) == "x && y"
114
+ assert jscode(x | y) == "x || y"
115
+ assert jscode(~x) == "!x"
116
+ assert jscode(x & y & z) == "x && y && z"
117
+ assert jscode(x | y | z) == "x || y || z"
118
+ assert jscode((x & y) | z) == "z || x && y"
119
+ assert jscode((x | y) & z) == "z && (x || y)"
120
+
121
+
122
+ def test_jscode_Piecewise():
123
+ expr = Piecewise((x, x < 1), (x**2, True))
124
+ p = jscode(expr)
125
+ s = \
126
+ """\
127
+ ((x < 1) ? (
128
+ x
129
+ )
130
+ : (
131
+ Math.pow(x, 2)
132
+ ))\
133
+ """
134
+ assert p == s
135
+ assert jscode(expr, assign_to="c") == (
136
+ "if (x < 1) {\n"
137
+ " c = x;\n"
138
+ "}\n"
139
+ "else {\n"
140
+ " c = Math.pow(x, 2);\n"
141
+ "}")
142
+ # Check that Piecewise without a True (default) condition error
143
+ expr = Piecewise((x, x < 1), (x**2, x > 1), (sin(x), x > 0))
144
+ raises(ValueError, lambda: jscode(expr))
145
+
146
+
147
+ def test_jscode_Piecewise_deep():
148
+ p = jscode(2*Piecewise((x, x < 1), (x**2, True)))
149
+ s = \
150
+ """\
151
+ 2*((x < 1) ? (
152
+ x
153
+ )
154
+ : (
155
+ Math.pow(x, 2)
156
+ ))\
157
+ """
158
+ assert p == s
159
+
160
+
161
+ def test_jscode_settings():
162
+ raises(TypeError, lambda: jscode(sin(x), method="garbage"))
163
+
164
+
165
+ def test_jscode_Indexed():
166
+ n, m, o = symbols('n m o', integer=True)
167
+ i, j, k = Idx('i', n), Idx('j', m), Idx('k', o)
168
+ p = JavascriptCodePrinter()
169
+ p._not_c = set()
170
+
171
+ x = IndexedBase('x')[j]
172
+ assert p._print_Indexed(x) == 'x[j]'
173
+ A = IndexedBase('A')[i, j]
174
+ assert p._print_Indexed(A) == 'A[%s]' % (m*i+j)
175
+ B = IndexedBase('B')[i, j, k]
176
+ assert p._print_Indexed(B) == 'B[%s]' % (i*o*m+j*o+k)
177
+
178
+ assert p._not_c == set()
179
+
180
+
181
+ def test_jscode_loops_matrix_vector():
182
+ n, m = symbols('n m', integer=True)
183
+ A = IndexedBase('A')
184
+ x = IndexedBase('x')
185
+ y = IndexedBase('y')
186
+ i = Idx('i', m)
187
+ j = Idx('j', n)
188
+
189
+ s = (
190
+ 'for (var i=0; i<m; i++){\n'
191
+ ' y[i] = 0;\n'
192
+ '}\n'
193
+ 'for (var i=0; i<m; i++){\n'
194
+ ' for (var j=0; j<n; j++){\n'
195
+ ' y[i] = A[n*i + j]*x[j] + y[i];\n'
196
+ ' }\n'
197
+ '}'
198
+ )
199
+ c = jscode(A[i, j]*x[j], assign_to=y[i])
200
+ assert c == s
201
+
202
+
203
+ def test_dummy_loops():
204
+ i, m = symbols('i m', integer=True, cls=Dummy)
205
+ x = IndexedBase('x')
206
+ y = IndexedBase('y')
207
+ i = Idx(i, m)
208
+
209
+ expected = (
210
+ 'for (var i_%(icount)i=0; i_%(icount)i<m_%(mcount)i; i_%(icount)i++){\n'
211
+ ' y[i_%(icount)i] = x[i_%(icount)i];\n'
212
+ '}'
213
+ ) % {'icount': i.label.dummy_index, 'mcount': m.dummy_index}
214
+ code = jscode(x[i], assign_to=y[i])
215
+ assert code == expected
216
+
217
+
218
+ def test_jscode_loops_add():
219
+ n, m = symbols('n m', integer=True)
220
+ A = IndexedBase('A')
221
+ x = IndexedBase('x')
222
+ y = IndexedBase('y')
223
+ z = IndexedBase('z')
224
+ i = Idx('i', m)
225
+ j = Idx('j', n)
226
+
227
+ s = (
228
+ 'for (var i=0; i<m; i++){\n'
229
+ ' y[i] = x[i] + z[i];\n'
230
+ '}\n'
231
+ 'for (var i=0; i<m; i++){\n'
232
+ ' for (var j=0; j<n; j++){\n'
233
+ ' y[i] = A[n*i + j]*x[j] + y[i];\n'
234
+ ' }\n'
235
+ '}'
236
+ )
237
+ c = jscode(A[i, j]*x[j] + x[i] + z[i], assign_to=y[i])
238
+ assert c == s
239
+
240
+
241
+ def test_jscode_loops_multiple_contractions():
242
+ n, m, o, p = symbols('n m o p', integer=True)
243
+ a = IndexedBase('a')
244
+ b = IndexedBase('b')
245
+ y = IndexedBase('y')
246
+ i = Idx('i', m)
247
+ j = Idx('j', n)
248
+ k = Idx('k', o)
249
+ l = Idx('l', p)
250
+
251
+ s = (
252
+ 'for (var i=0; i<m; i++){\n'
253
+ ' y[i] = 0;\n'
254
+ '}\n'
255
+ 'for (var i=0; i<m; i++){\n'
256
+ ' for (var j=0; j<n; j++){\n'
257
+ ' for (var k=0; k<o; k++){\n'
258
+ ' for (var l=0; l<p; l++){\n'
259
+ ' y[i] = a[%s]*b[%s] + y[i];\n' % (i*n*o*p + j*o*p + k*p + l, j*o*p + k*p + l) +\
260
+ ' }\n'
261
+ ' }\n'
262
+ ' }\n'
263
+ '}'
264
+ )
265
+ c = jscode(b[j, k, l]*a[i, j, k, l], assign_to=y[i])
266
+ assert c == s
267
+
268
+
269
+ def test_jscode_loops_addfactor():
270
+ n, m, o, p = symbols('n m o p', integer=True)
271
+ a = IndexedBase('a')
272
+ b = IndexedBase('b')
273
+ c = IndexedBase('c')
274
+ y = IndexedBase('y')
275
+ i = Idx('i', m)
276
+ j = Idx('j', n)
277
+ k = Idx('k', o)
278
+ l = Idx('l', p)
279
+
280
+ s = (
281
+ 'for (var i=0; i<m; i++){\n'
282
+ ' y[i] = 0;\n'
283
+ '}\n'
284
+ 'for (var i=0; i<m; i++){\n'
285
+ ' for (var j=0; j<n; j++){\n'
286
+ ' for (var k=0; k<o; k++){\n'
287
+ ' for (var l=0; l<p; l++){\n'
288
+ ' y[i] = (a[%s] + b[%s])*c[%s] + y[i];\n' % (i*n*o*p + j*o*p + k*p + l, i*n*o*p + j*o*p + k*p + l, j*o*p + k*p + l) +\
289
+ ' }\n'
290
+ ' }\n'
291
+ ' }\n'
292
+ '}'
293
+ )
294
+ c = jscode((a[i, j, k, l] + b[i, j, k, l])*c[j, k, l], assign_to=y[i])
295
+ assert c == s
296
+
297
+
298
+ def test_jscode_loops_multiple_terms():
299
+ n, m, o, p = symbols('n m o p', integer=True)
300
+ a = IndexedBase('a')
301
+ b = IndexedBase('b')
302
+ c = IndexedBase('c')
303
+ y = IndexedBase('y')
304
+ i = Idx('i', m)
305
+ j = Idx('j', n)
306
+ k = Idx('k', o)
307
+
308
+ s0 = (
309
+ 'for (var i=0; i<m; i++){\n'
310
+ ' y[i] = 0;\n'
311
+ '}\n'
312
+ )
313
+ s1 = (
314
+ 'for (var i=0; i<m; i++){\n'
315
+ ' for (var j=0; j<n; j++){\n'
316
+ ' for (var k=0; k<o; k++){\n'
317
+ ' y[i] = b[j]*b[k]*c[%s] + y[i];\n' % (i*n*o + j*o + k) +\
318
+ ' }\n'
319
+ ' }\n'
320
+ '}\n'
321
+ )
322
+ s2 = (
323
+ 'for (var i=0; i<m; i++){\n'
324
+ ' for (var k=0; k<o; k++){\n'
325
+ ' y[i] = a[%s]*b[k] + y[i];\n' % (i*o + k) +\
326
+ ' }\n'
327
+ '}\n'
328
+ )
329
+ s3 = (
330
+ 'for (var i=0; i<m; i++){\n'
331
+ ' for (var j=0; j<n; j++){\n'
332
+ ' y[i] = a[%s]*b[j] + y[i];\n' % (i*n + j) +\
333
+ ' }\n'
334
+ '}\n'
335
+ )
336
+ c = jscode(
337
+ b[j]*a[i, j] + b[k]*a[i, k] + b[j]*b[k]*c[i, j, k], assign_to=y[i])
338
+ assert (c == s0 + s1 + s2 + s3[:-1] or
339
+ c == s0 + s1 + s3 + s2[:-1] or
340
+ c == s0 + s2 + s1 + s3[:-1] or
341
+ c == s0 + s2 + s3 + s1[:-1] or
342
+ c == s0 + s3 + s1 + s2[:-1] or
343
+ c == s0 + s3 + s2 + s1[:-1])
344
+
345
+
346
+ def test_Matrix_printing():
347
+ # Test returning a Matrix
348
+ mat = Matrix([x*y, Piecewise((2 + x, y>0), (y, True)), sin(z)])
349
+ A = MatrixSymbol('A', 3, 1)
350
+ assert jscode(mat, A) == (
351
+ "A[0] = x*y;\n"
352
+ "if (y > 0) {\n"
353
+ " A[1] = x + 2;\n"
354
+ "}\n"
355
+ "else {\n"
356
+ " A[1] = y;\n"
357
+ "}\n"
358
+ "A[2] = Math.sin(z);")
359
+ # Test using MatrixElements in expressions
360
+ expr = Piecewise((2*A[2, 0], x > 0), (A[2, 0], True)) + sin(A[1, 0]) + A[0, 0]
361
+ assert jscode(expr) == (
362
+ "((x > 0) ? (\n"
363
+ " 2*A[2]\n"
364
+ ")\n"
365
+ ": (\n"
366
+ " A[2]\n"
367
+ ")) + Math.sin(A[1]) + A[0]")
368
+ # Test using MatrixElements in a Matrix
369
+ q = MatrixSymbol('q', 5, 1)
370
+ M = MatrixSymbol('M', 3, 3)
371
+ m = Matrix([[sin(q[1,0]), 0, cos(q[2,0])],
372
+ [q[1,0] + q[2,0], q[3, 0], 5],
373
+ [2*q[4, 0]/q[1,0], sqrt(q[0,0]) + 4, 0]])
374
+ assert jscode(m, M) == (
375
+ "M[0] = Math.sin(q[1]);\n"
376
+ "M[1] = 0;\n"
377
+ "M[2] = Math.cos(q[2]);\n"
378
+ "M[3] = q[1] + q[2];\n"
379
+ "M[4] = q[3];\n"
380
+ "M[5] = 5;\n"
381
+ "M[6] = 2*q[4]/q[1];\n"
382
+ "M[7] = Math.sqrt(q[0]) + 4;\n"
383
+ "M[8] = 0;")
384
+
385
+
386
+ def test_MatrixElement_printing():
387
+ # test cases for issue #11821
388
+ A = MatrixSymbol("A", 1, 3)
389
+ B = MatrixSymbol("B", 1, 3)
390
+ C = MatrixSymbol("C", 1, 3)
391
+
392
+ assert(jscode(A[0, 0]) == "A[0]")
393
+ assert(jscode(3 * A[0, 0]) == "3*A[0]")
394
+
395
+ F = C[0, 0].subs(C, A - B)
396
+ assert(jscode(F) == "(A - B)[0]")
lib/python3.12/site-packages/sympy/printing/tests/test_julia.py ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.core import (S, pi, oo, symbols, Function, Rational, Integer,
2
+ Tuple, Symbol, Eq, Ne, Le, Lt, Gt, Ge)
3
+ from sympy.core import EulerGamma, GoldenRatio, Catalan, Lambda, Mul, Pow
4
+ from sympy.functions import Piecewise, sqrt, ceiling, exp, sin, cos
5
+ from sympy.testing.pytest import raises
6
+ from sympy.utilities.lambdify import implemented_function
7
+ from sympy.matrices import (eye, Matrix, MatrixSymbol, Identity,
8
+ HadamardProduct, SparseMatrix)
9
+ from sympy.functions.special.bessel import (jn, yn, besselj, bessely, besseli,
10
+ besselk, hankel1, hankel2, airyai,
11
+ airybi, airyaiprime, airybiprime)
12
+ from sympy.testing.pytest import XFAIL
13
+
14
+ from sympy.printing.julia import julia_code
15
+
16
+ x, y, z = symbols('x,y,z')
17
+
18
+
19
+ def test_Integer():
20
+ assert julia_code(Integer(67)) == "67"
21
+ assert julia_code(Integer(-1)) == "-1"
22
+
23
+
24
+ def test_Rational():
25
+ assert julia_code(Rational(3, 7)) == "3 // 7"
26
+ assert julia_code(Rational(18, 9)) == "2"
27
+ assert julia_code(Rational(3, -7)) == "-3 // 7"
28
+ assert julia_code(Rational(-3, -7)) == "3 // 7"
29
+ assert julia_code(x + Rational(3, 7)) == "x + 3 // 7"
30
+ assert julia_code(Rational(3, 7)*x) == "(3 // 7) * x"
31
+
32
+
33
+ def test_Relational():
34
+ assert julia_code(Eq(x, y)) == "x == y"
35
+ assert julia_code(Ne(x, y)) == "x != y"
36
+ assert julia_code(Le(x, y)) == "x <= y"
37
+ assert julia_code(Lt(x, y)) == "x < y"
38
+ assert julia_code(Gt(x, y)) == "x > y"
39
+ assert julia_code(Ge(x, y)) == "x >= y"
40
+
41
+
42
+ def test_Function():
43
+ assert julia_code(sin(x) ** cos(x)) == "sin(x) .^ cos(x)"
44
+ assert julia_code(abs(x)) == "abs(x)"
45
+ assert julia_code(ceiling(x)) == "ceil(x)"
46
+
47
+
48
+ def test_Pow():
49
+ assert julia_code(x**3) == "x .^ 3"
50
+ assert julia_code(x**(y**3)) == "x .^ (y .^ 3)"
51
+ assert julia_code(x**Rational(2, 3)) == 'x .^ (2 // 3)'
52
+ g = implemented_function('g', Lambda(x, 2*x))
53
+ assert julia_code(1/(g(x)*3.5)**(x - y**x)/(x**2 + y)) == \
54
+ "(3.5 * 2 * x) .^ (-x + y .^ x) ./ (x .^ 2 + y)"
55
+ # For issue 14160
56
+ assert julia_code(Mul(-2, x, Pow(Mul(y,y,evaluate=False), -1, evaluate=False),
57
+ evaluate=False)) == '-2 * x ./ (y .* y)'
58
+
59
+
60
+ def test_basic_ops():
61
+ assert julia_code(x*y) == "x .* y"
62
+ assert julia_code(x + y) == "x + y"
63
+ assert julia_code(x - y) == "x - y"
64
+ assert julia_code(-x) == "-x"
65
+
66
+
67
+ def test_1_over_x_and_sqrt():
68
+ # 1.0 and 0.5 would do something different in regular StrPrinter,
69
+ # but these are exact in IEEE floating point so no different here.
70
+ assert julia_code(1/x) == '1 ./ x'
71
+ assert julia_code(x**-1) == julia_code(x**-1.0) == '1 ./ x'
72
+ assert julia_code(1/sqrt(x)) == '1 ./ sqrt(x)'
73
+ assert julia_code(x**-S.Half) == julia_code(x**-0.5) == '1 ./ sqrt(x)'
74
+ assert julia_code(sqrt(x)) == 'sqrt(x)'
75
+ assert julia_code(x**S.Half) == julia_code(x**0.5) == 'sqrt(x)'
76
+ assert julia_code(1/pi) == '1 / pi'
77
+ assert julia_code(pi**-1) == julia_code(pi**-1.0) == '1 / pi'
78
+ assert julia_code(pi**-0.5) == '1 / sqrt(pi)'
79
+
80
+
81
+ def test_mix_number_mult_symbols():
82
+ assert julia_code(3*x) == "3 * x"
83
+ assert julia_code(pi*x) == "pi * x"
84
+ assert julia_code(3/x) == "3 ./ x"
85
+ assert julia_code(pi/x) == "pi ./ x"
86
+ assert julia_code(x/3) == "x / 3"
87
+ assert julia_code(x/pi) == "x / pi"
88
+ assert julia_code(x*y) == "x .* y"
89
+ assert julia_code(3*x*y) == "3 * x .* y"
90
+ assert julia_code(3*pi*x*y) == "3 * pi * x .* y"
91
+ assert julia_code(x/y) == "x ./ y"
92
+ assert julia_code(3*x/y) == "3 * x ./ y"
93
+ assert julia_code(x*y/z) == "x .* y ./ z"
94
+ assert julia_code(x/y*z) == "x .* z ./ y"
95
+ assert julia_code(1/x/y) == "1 ./ (x .* y)"
96
+ assert julia_code(2*pi*x/y/z) == "2 * pi * x ./ (y .* z)"
97
+ assert julia_code(3*pi/x) == "3 * pi ./ x"
98
+ assert julia_code(S(3)/5) == "3 // 5"
99
+ assert julia_code(S(3)/5*x) == "(3 // 5) * x"
100
+ assert julia_code(x/y/z) == "x ./ (y .* z)"
101
+ assert julia_code((x+y)/z) == "(x + y) ./ z"
102
+ assert julia_code((x+y)/(z+x)) == "(x + y) ./ (x + z)"
103
+ assert julia_code((x+y)/EulerGamma) == "(x + y) / eulergamma"
104
+ assert julia_code(x/3/pi) == "x / (3 * pi)"
105
+ assert julia_code(S(3)/5*x*y/pi) == "(3 // 5) * x .* y / pi"
106
+
107
+
108
+ def test_mix_number_pow_symbols():
109
+ assert julia_code(pi**3) == 'pi ^ 3'
110
+ assert julia_code(x**2) == 'x .^ 2'
111
+ assert julia_code(x**(pi**3)) == 'x .^ (pi ^ 3)'
112
+ assert julia_code(x**y) == 'x .^ y'
113
+ assert julia_code(x**(y**z)) == 'x .^ (y .^ z)'
114
+ assert julia_code((x**y)**z) == '(x .^ y) .^ z'
115
+
116
+
117
+ def test_imag():
118
+ I = S('I')
119
+ assert julia_code(I) == "im"
120
+ assert julia_code(5*I) == "5im"
121
+ assert julia_code((S(3)/2)*I) == "(3 // 2) * im"
122
+ assert julia_code(3+4*I) == "3 + 4im"
123
+
124
+
125
+ def test_constants():
126
+ assert julia_code(pi) == "pi"
127
+ assert julia_code(oo) == "Inf"
128
+ assert julia_code(-oo) == "-Inf"
129
+ assert julia_code(S.NegativeInfinity) == "-Inf"
130
+ assert julia_code(S.NaN) == "NaN"
131
+ assert julia_code(S.Exp1) == "e"
132
+ assert julia_code(exp(1)) == "e"
133
+
134
+
135
+ def test_constants_other():
136
+ assert julia_code(2*GoldenRatio) == "2 * golden"
137
+ assert julia_code(2*Catalan) == "2 * catalan"
138
+ assert julia_code(2*EulerGamma) == "2 * eulergamma"
139
+
140
+
141
+ def test_boolean():
142
+ assert julia_code(x & y) == "x && y"
143
+ assert julia_code(x | y) == "x || y"
144
+ assert julia_code(~x) == "!x"
145
+ assert julia_code(x & y & z) == "x && y && z"
146
+ assert julia_code(x | y | z) == "x || y || z"
147
+ assert julia_code((x & y) | z) == "z || x && y"
148
+ assert julia_code((x | y) & z) == "z && (x || y)"
149
+
150
+
151
+ def test_Matrices():
152
+ assert julia_code(Matrix(1, 1, [10])) == "[10]"
153
+ A = Matrix([[1, sin(x/2), abs(x)],
154
+ [0, 1, pi],
155
+ [0, exp(1), ceiling(x)]]);
156
+ expected = ("[1 sin(x / 2) abs(x);\n"
157
+ "0 1 pi;\n"
158
+ "0 e ceil(x)]")
159
+ assert julia_code(A) == expected
160
+ # row and columns
161
+ assert julia_code(A[:,0]) == "[1, 0, 0]"
162
+ assert julia_code(A[0,:]) == "[1 sin(x / 2) abs(x)]"
163
+ # empty matrices
164
+ assert julia_code(Matrix(0, 0, [])) == 'zeros(0, 0)'
165
+ assert julia_code(Matrix(0, 3, [])) == 'zeros(0, 3)'
166
+ # annoying to read but correct
167
+ assert julia_code(Matrix([[x, x - y, -y]])) == "[x x - y -y]"
168
+
169
+
170
+ def test_vector_entries_hadamard():
171
+ # For a row or column, user might to use the other dimension
172
+ A = Matrix([[1, sin(2/x), 3*pi/x/5]])
173
+ assert julia_code(A) == "[1 sin(2 ./ x) (3 // 5) * pi ./ x]"
174
+ assert julia_code(A.T) == "[1, sin(2 ./ x), (3 // 5) * pi ./ x]"
175
+
176
+
177
+ @XFAIL
178
+ def test_Matrices_entries_not_hadamard():
179
+ # For Matrix with col >= 2, row >= 2, they need to be scalars
180
+ # FIXME: is it worth worrying about this? Its not wrong, just
181
+ # leave it user's responsibility to put scalar data for x.
182
+ A = Matrix([[1, sin(2/x), 3*pi/x/5], [1, 2, x*y]])
183
+ expected = ("[1 sin(2/x) 3*pi/(5*x);\n"
184
+ "1 2 x*y]") # <- we give x.*y
185
+ assert julia_code(A) == expected
186
+
187
+
188
+ def test_MatrixSymbol():
189
+ n = Symbol('n', integer=True)
190
+ A = MatrixSymbol('A', n, n)
191
+ B = MatrixSymbol('B', n, n)
192
+ assert julia_code(A*B) == "A * B"
193
+ assert julia_code(B*A) == "B * A"
194
+ assert julia_code(2*A*B) == "2 * A * B"
195
+ assert julia_code(B*2*A) == "2 * B * A"
196
+ assert julia_code(A*(B + 3*Identity(n))) == "A * (3 * eye(n) + B)"
197
+ assert julia_code(A**(x**2)) == "A ^ (x .^ 2)"
198
+ assert julia_code(A**3) == "A ^ 3"
199
+ assert julia_code(A**S.Half) == "A ^ (1 // 2)"
200
+
201
+
202
+ def test_special_matrices():
203
+ assert julia_code(6*Identity(3)) == "6 * eye(3)"
204
+
205
+
206
+ def test_containers():
207
+ assert julia_code([1, 2, 3, [4, 5, [6, 7]], 8, [9, 10], 11]) == \
208
+ "Any[1, 2, 3, Any[4, 5, Any[6, 7]], 8, Any[9, 10], 11]"
209
+ assert julia_code((1, 2, (3, 4))) == "(1, 2, (3, 4))"
210
+ assert julia_code([1]) == "Any[1]"
211
+ assert julia_code((1,)) == "(1,)"
212
+ assert julia_code(Tuple(*[1, 2, 3])) == "(1, 2, 3)"
213
+ assert julia_code((1, x*y, (3, x**2))) == "(1, x .* y, (3, x .^ 2))"
214
+ # scalar, matrix, empty matrix and empty list
215
+ assert julia_code((1, eye(3), Matrix(0, 0, []), [])) == "(1, [1 0 0;\n0 1 0;\n0 0 1], zeros(0, 0), Any[])"
216
+
217
+
218
+ def test_julia_noninline():
219
+ source = julia_code((x+y)/Catalan, assign_to='me', inline=False)
220
+ expected = (
221
+ "const Catalan = %s\n"
222
+ "me = (x + y) / Catalan"
223
+ ) % Catalan.evalf(17)
224
+ assert source == expected
225
+
226
+
227
+ def test_julia_piecewise():
228
+ expr = Piecewise((x, x < 1), (x**2, True))
229
+ assert julia_code(expr) == "((x < 1) ? (x) : (x .^ 2))"
230
+ assert julia_code(expr, assign_to="r") == (
231
+ "r = ((x < 1) ? (x) : (x .^ 2))")
232
+ assert julia_code(expr, assign_to="r", inline=False) == (
233
+ "if (x < 1)\n"
234
+ " r = x\n"
235
+ "else\n"
236
+ " r = x .^ 2\n"
237
+ "end")
238
+ expr = Piecewise((x**2, x < 1), (x**3, x < 2), (x**4, x < 3), (x**5, True))
239
+ expected = ("((x < 1) ? (x .^ 2) :\n"
240
+ "(x < 2) ? (x .^ 3) :\n"
241
+ "(x < 3) ? (x .^ 4) : (x .^ 5))")
242
+ assert julia_code(expr) == expected
243
+ assert julia_code(expr, assign_to="r") == "r = " + expected
244
+ assert julia_code(expr, assign_to="r", inline=False) == (
245
+ "if (x < 1)\n"
246
+ " r = x .^ 2\n"
247
+ "elseif (x < 2)\n"
248
+ " r = x .^ 3\n"
249
+ "elseif (x < 3)\n"
250
+ " r = x .^ 4\n"
251
+ "else\n"
252
+ " r = x .^ 5\n"
253
+ "end")
254
+ # Check that Piecewise without a True (default) condition error
255
+ expr = Piecewise((x, x < 1), (x**2, x > 1), (sin(x), x > 0))
256
+ raises(ValueError, lambda: julia_code(expr))
257
+
258
+
259
+ def test_julia_piecewise_times_const():
260
+ pw = Piecewise((x, x < 1), (x**2, True))
261
+ assert julia_code(2*pw) == "2 * ((x < 1) ? (x) : (x .^ 2))"
262
+ assert julia_code(pw/x) == "((x < 1) ? (x) : (x .^ 2)) ./ x"
263
+ assert julia_code(pw/(x*y)) == "((x < 1) ? (x) : (x .^ 2)) ./ (x .* y)"
264
+ assert julia_code(pw/3) == "((x < 1) ? (x) : (x .^ 2)) / 3"
265
+
266
+
267
+ def test_julia_matrix_assign_to():
268
+ A = Matrix([[1, 2, 3]])
269
+ assert julia_code(A, assign_to='a') == "a = [1 2 3]"
270
+ A = Matrix([[1, 2], [3, 4]])
271
+ assert julia_code(A, assign_to='A') == "A = [1 2;\n3 4]"
272
+
273
+
274
+ def test_julia_matrix_assign_to_more():
275
+ # assigning to Symbol or MatrixSymbol requires lhs/rhs match
276
+ A = Matrix([[1, 2, 3]])
277
+ B = MatrixSymbol('B', 1, 3)
278
+ C = MatrixSymbol('C', 2, 3)
279
+ assert julia_code(A, assign_to=B) == "B = [1 2 3]"
280
+ raises(ValueError, lambda: julia_code(A, assign_to=x))
281
+ raises(ValueError, lambda: julia_code(A, assign_to=C))
282
+
283
+
284
+ def test_julia_matrix_1x1():
285
+ A = Matrix([[3]])
286
+ B = MatrixSymbol('B', 1, 1)
287
+ C = MatrixSymbol('C', 1, 2)
288
+ assert julia_code(A, assign_to=B) == "B = [3]"
289
+ # FIXME?
290
+ #assert julia_code(A, assign_to=x) == "x = [3]"
291
+ raises(ValueError, lambda: julia_code(A, assign_to=C))
292
+
293
+
294
+ def test_julia_matrix_elements():
295
+ A = Matrix([[x, 2, x*y]])
296
+ assert julia_code(A[0, 0]**2 + A[0, 1] + A[0, 2]) == "x .^ 2 + x .* y + 2"
297
+ A = MatrixSymbol('AA', 1, 3)
298
+ assert julia_code(A) == "AA"
299
+ assert julia_code(A[0, 0]**2 + sin(A[0,1]) + A[0,2]) == \
300
+ "sin(AA[1,2]) + AA[1,1] .^ 2 + AA[1,3]"
301
+ assert julia_code(sum(A)) == "AA[1,1] + AA[1,2] + AA[1,3]"
302
+
303
+
304
+ def test_julia_boolean():
305
+ assert julia_code(True) == "true"
306
+ assert julia_code(S.true) == "true"
307
+ assert julia_code(False) == "false"
308
+ assert julia_code(S.false) == "false"
309
+
310
+
311
+ def test_julia_not_supported():
312
+ with raises(NotImplementedError):
313
+ julia_code(S.ComplexInfinity)
314
+
315
+ f = Function('f')
316
+ assert julia_code(f(x).diff(x), strict=False) == (
317
+ "# Not supported in Julia:\n"
318
+ "# Derivative\n"
319
+ "Derivative(f(x), x)"
320
+ )
321
+
322
+
323
+ def test_trick_indent_with_end_else_words():
324
+ # words starting with "end" or "else" do not confuse the indenter
325
+ t1 = S('endless');
326
+ t2 = S('elsewhere');
327
+ pw = Piecewise((t1, x < 0), (t2, x <= 1), (1, True))
328
+ assert julia_code(pw, inline=False) == (
329
+ "if (x < 0)\n"
330
+ " endless\n"
331
+ "elseif (x <= 1)\n"
332
+ " elsewhere\n"
333
+ "else\n"
334
+ " 1\n"
335
+ "end")
336
+
337
+
338
+ def test_haramard():
339
+ A = MatrixSymbol('A', 3, 3)
340
+ B = MatrixSymbol('B', 3, 3)
341
+ v = MatrixSymbol('v', 3, 1)
342
+ h = MatrixSymbol('h', 1, 3)
343
+ C = HadamardProduct(A, B)
344
+ assert julia_code(C) == "A .* B"
345
+ assert julia_code(C*v) == "(A .* B) * v"
346
+ assert julia_code(h*C*v) == "h * (A .* B) * v"
347
+ assert julia_code(C*A) == "(A .* B) * A"
348
+ # mixing Hadamard and scalar strange b/c we vectorize scalars
349
+ assert julia_code(C*x*y) == "(x .* y) * (A .* B)"
350
+
351
+
352
+ def test_sparse():
353
+ M = SparseMatrix(5, 6, {})
354
+ M[2, 2] = 10;
355
+ M[1, 2] = 20;
356
+ M[1, 3] = 22;
357
+ M[0, 3] = 30;
358
+ M[3, 0] = x*y;
359
+ assert julia_code(M) == (
360
+ "sparse([4, 2, 3, 1, 2], [1, 3, 3, 4, 4], [x .* y, 20, 10, 30, 22], 5, 6)"
361
+ )
362
+
363
+
364
+ def test_specfun():
365
+ n = Symbol('n')
366
+ for f in [besselj, bessely, besseli, besselk]:
367
+ assert julia_code(f(n, x)) == f.__name__ + '(n, x)'
368
+ for f in [airyai, airyaiprime, airybi, airybiprime]:
369
+ assert julia_code(f(x)) == f.__name__ + '(x)'
370
+ assert julia_code(hankel1(n, x)) == 'hankelh1(n, x)'
371
+ assert julia_code(hankel2(n, x)) == 'hankelh2(n, x)'
372
+ assert julia_code(jn(n, x)) == 'sqrt(2) * sqrt(pi) * sqrt(1 ./ x) .* besselj(n + 1 // 2, x) / 2'
373
+ assert julia_code(yn(n, x)) == 'sqrt(2) * sqrt(pi) * sqrt(1 ./ x) .* bessely(n + 1 // 2, x) / 2'
374
+
375
+
376
+ def test_MatrixElement_printing():
377
+ # test cases for issue #11821
378
+ A = MatrixSymbol("A", 1, 3)
379
+ B = MatrixSymbol("B", 1, 3)
380
+ C = MatrixSymbol("C", 1, 3)
381
+
382
+ assert(julia_code(A[0, 0]) == "A[1,1]")
383
+ assert(julia_code(3 * A[0, 0]) == "3 * A[1,1]")
384
+
385
+ F = C[0, 0].subs(C, A - B)
386
+ assert(julia_code(F) == "(A - B)[1,1]")
lib/python3.12/site-packages/sympy/printing/tests/test_latex.py ADDED
The diff for this file is too large to render. See raw diff
 
lib/python3.12/site-packages/sympy/printing/tests/test_llvmjit.py ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.external import import_module
2
+ from sympy.testing.pytest import raises
3
+ import ctypes
4
+
5
+
6
+ if import_module('llvmlite'):
7
+ import sympy.printing.llvmjitcode as g
8
+ else:
9
+ disabled = True
10
+
11
+ import sympy
12
+ from sympy.abc import a, b, n
13
+
14
+
15
+ # copied from numpy.isclose documentation
16
+ def isclose(a, b):
17
+ rtol = 1e-5
18
+ atol = 1e-8
19
+ return abs(a-b) <= atol + rtol*abs(b)
20
+
21
+
22
+ def test_simple_expr():
23
+ e = a + 1.0
24
+ f = g.llvm_callable([a], e)
25
+ res = float(e.subs({a: 4.0}).evalf())
26
+ jit_res = f(4.0)
27
+
28
+ assert isclose(jit_res, res)
29
+
30
+
31
+ def test_two_arg():
32
+ e = 4.0*a + b + 3.0
33
+ f = g.llvm_callable([a, b], e)
34
+ res = float(e.subs({a: 4.0, b: 3.0}).evalf())
35
+ jit_res = f(4.0, 3.0)
36
+
37
+ assert isclose(jit_res, res)
38
+
39
+
40
+ def test_func():
41
+ e = 4.0*sympy.exp(-a)
42
+ f = g.llvm_callable([a], e)
43
+ res = float(e.subs({a: 1.5}).evalf())
44
+ jit_res = f(1.5)
45
+
46
+ assert isclose(jit_res, res)
47
+
48
+
49
+ def test_two_func():
50
+ e = 4.0*sympy.exp(-a) + sympy.exp(b)
51
+ f = g.llvm_callable([a, b], e)
52
+ res = float(e.subs({a: 1.5, b: 2.0}).evalf())
53
+ jit_res = f(1.5, 2.0)
54
+
55
+ assert isclose(jit_res, res)
56
+
57
+
58
+ def test_two_sqrt():
59
+ e = 4.0*sympy.sqrt(a) + sympy.sqrt(b)
60
+ f = g.llvm_callable([a, b], e)
61
+ res = float(e.subs({a: 1.5, b: 2.0}).evalf())
62
+ jit_res = f(1.5, 2.0)
63
+
64
+ assert isclose(jit_res, res)
65
+
66
+
67
+ def test_two_pow():
68
+ e = a**1.5 + b**7
69
+ f = g.llvm_callable([a, b], e)
70
+ res = float(e.subs({a: 1.5, b: 2.0}).evalf())
71
+ jit_res = f(1.5, 2.0)
72
+
73
+ assert isclose(jit_res, res)
74
+
75
+
76
+ def test_callback():
77
+ e = a + 1.2
78
+ f = g.llvm_callable([a], e, callback_type='scipy.integrate.test')
79
+ m = ctypes.c_int(1)
80
+ array_type = ctypes.c_double * 1
81
+ inp = {a: 2.2}
82
+ array = array_type(inp[a])
83
+ jit_res = f(m, array)
84
+
85
+ res = float(e.subs(inp).evalf())
86
+
87
+ assert isclose(jit_res, res)
88
+
89
+
90
+ def test_callback_cubature():
91
+ e = a + 1.2
92
+ f = g.llvm_callable([a], e, callback_type='cubature')
93
+ m = ctypes.c_int(1)
94
+ array_type = ctypes.c_double * 1
95
+ inp = {a: 2.2}
96
+ array = array_type(inp[a])
97
+ out_array = array_type(0.0)
98
+ jit_ret = f(m, array, None, m, out_array)
99
+
100
+ assert jit_ret == 0
101
+
102
+ res = float(e.subs(inp).evalf())
103
+
104
+ assert isclose(out_array[0], res)
105
+
106
+
107
+ def test_callback_two():
108
+ e = 3*a*b
109
+ f = g.llvm_callable([a, b], e, callback_type='scipy.integrate.test')
110
+ m = ctypes.c_int(2)
111
+ array_type = ctypes.c_double * 2
112
+ inp = {a: 0.2, b: 1.7}
113
+ array = array_type(inp[a], inp[b])
114
+ jit_res = f(m, array)
115
+
116
+ res = float(e.subs(inp).evalf())
117
+
118
+ assert isclose(jit_res, res)
119
+
120
+
121
+ def test_callback_alt_two():
122
+ d = sympy.IndexedBase('d')
123
+ e = 3*d[0]*d[1]
124
+ f = g.llvm_callable([n, d], e, callback_type='scipy.integrate.test')
125
+ m = ctypes.c_int(2)
126
+ array_type = ctypes.c_double * 2
127
+ inp = {d[0]: 0.2, d[1]: 1.7}
128
+ array = array_type(inp[d[0]], inp[d[1]])
129
+ jit_res = f(m, array)
130
+
131
+ res = float(e.subs(inp).evalf())
132
+
133
+ assert isclose(jit_res, res)
134
+
135
+
136
+ def test_multiple_statements():
137
+ # Match return from CSE
138
+ e = [[(b, 4.0*a)], [b + 5]]
139
+ f = g.llvm_callable([a], e)
140
+ b_val = e[0][0][1].subs({a: 1.5})
141
+ res = float(e[1][0].subs({b: b_val}).evalf())
142
+ jit_res = f(1.5)
143
+ assert isclose(jit_res, res)
144
+
145
+ f_callback = g.llvm_callable([a], e, callback_type='scipy.integrate.test')
146
+ m = ctypes.c_int(1)
147
+ array_type = ctypes.c_double * 1
148
+ array = array_type(1.5)
149
+ jit_callback_res = f_callback(m, array)
150
+ assert isclose(jit_callback_res, res)
151
+
152
+
153
+ def test_cse():
154
+ e = a*a + b*b + sympy.exp(-a*a - b*b)
155
+ e2 = sympy.cse(e)
156
+ f = g.llvm_callable([a, b], e2)
157
+ res = float(e.subs({a: 2.3, b: 0.1}).evalf())
158
+ jit_res = f(2.3, 0.1)
159
+
160
+ assert isclose(jit_res, res)
161
+
162
+
163
+ def eval_cse(e, sub_dict):
164
+ tmp_dict = {}
165
+ for tmp_name, tmp_expr in e[0]:
166
+ e2 = tmp_expr.subs(sub_dict)
167
+ e3 = e2.subs(tmp_dict)
168
+ tmp_dict[tmp_name] = e3
169
+ return [e.subs(sub_dict).subs(tmp_dict) for e in e[1]]
170
+
171
+
172
+ def test_cse_multiple():
173
+ e1 = a*a
174
+ e2 = a*a + b*b
175
+ e3 = sympy.cse([e1, e2])
176
+
177
+ raises(NotImplementedError,
178
+ lambda: g.llvm_callable([a, b], e3, callback_type='scipy.integrate'))
179
+
180
+ f = g.llvm_callable([a, b], e3)
181
+ jit_res = f(0.1, 1.5)
182
+ assert len(jit_res) == 2
183
+ res = eval_cse(e3, {a: 0.1, b: 1.5})
184
+ assert isclose(res[0], jit_res[0])
185
+ assert isclose(res[1], jit_res[1])
186
+
187
+
188
+ def test_callback_cubature_multiple():
189
+ e1 = a*a
190
+ e2 = a*a + b*b
191
+ e3 = sympy.cse([e1, e2, 4*e2])
192
+ f = g.llvm_callable([a, b], e3, callback_type='cubature')
193
+
194
+ # Number of input variables
195
+ ndim = 2
196
+ # Number of output expression values
197
+ outdim = 3
198
+
199
+ m = ctypes.c_int(ndim)
200
+ fdim = ctypes.c_int(outdim)
201
+ array_type = ctypes.c_double * ndim
202
+ out_array_type = ctypes.c_double * outdim
203
+ inp = {a: 0.2, b: 1.5}
204
+ array = array_type(inp[a], inp[b])
205
+ out_array = out_array_type()
206
+ jit_ret = f(m, array, None, fdim, out_array)
207
+
208
+ assert jit_ret == 0
209
+
210
+ res = eval_cse(e3, inp)
211
+
212
+ assert isclose(out_array[0], res[0])
213
+ assert isclose(out_array[1], res[1])
214
+ assert isclose(out_array[2], res[2])
215
+
216
+
217
+ def test_symbol_not_found():
218
+ e = a*a + b
219
+ raises(LookupError, lambda: g.llvm_callable([a], e))
220
+
221
+
222
+ def test_bad_callback():
223
+ e = a
224
+ raises(ValueError, lambda: g.llvm_callable([a], e, callback_type='bad_callback'))
lib/python3.12/site-packages/sympy/printing/tests/test_maple.py ADDED
@@ -0,0 +1,381 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.core import (S, pi, oo, symbols, Function, Rational, Integer,
2
+ Tuple, Symbol, Eq, Ne, Le, Lt, Gt, Ge)
3
+ from sympy.core import EulerGamma, GoldenRatio, Catalan, Lambda, Mul, Pow
4
+ from sympy.functions import Piecewise, sqrt, ceiling, exp, sin, cos, sinc, lucas
5
+ from sympy.testing.pytest import raises
6
+ from sympy.utilities.lambdify import implemented_function
7
+ from sympy.matrices import (eye, Matrix, MatrixSymbol, Identity,
8
+ HadamardProduct, SparseMatrix)
9
+ from sympy.functions.special.bessel import besseli
10
+
11
+ from sympy.printing.maple import maple_code
12
+
13
+ x, y, z = symbols('x,y,z')
14
+
15
+
16
+ def test_Integer():
17
+ assert maple_code(Integer(67)) == "67"
18
+ assert maple_code(Integer(-1)) == "-1"
19
+
20
+
21
+ def test_Rational():
22
+ assert maple_code(Rational(3, 7)) == "3/7"
23
+ assert maple_code(Rational(18, 9)) == "2"
24
+ assert maple_code(Rational(3, -7)) == "-3/7"
25
+ assert maple_code(Rational(-3, -7)) == "3/7"
26
+ assert maple_code(x + Rational(3, 7)) == "x + 3/7"
27
+ assert maple_code(Rational(3, 7) * x) == '(3/7)*x'
28
+
29
+
30
+ def test_Relational():
31
+ assert maple_code(Eq(x, y)) == "x = y"
32
+ assert maple_code(Ne(x, y)) == "x <> y"
33
+ assert maple_code(Le(x, y)) == "x <= y"
34
+ assert maple_code(Lt(x, y)) == "x < y"
35
+ assert maple_code(Gt(x, y)) == "x > y"
36
+ assert maple_code(Ge(x, y)) == "x >= y"
37
+
38
+
39
+ def test_Function():
40
+ assert maple_code(sin(x) ** cos(x)) == "sin(x)^cos(x)"
41
+ assert maple_code(abs(x)) == "abs(x)"
42
+ assert maple_code(ceiling(x)) == "ceil(x)"
43
+
44
+
45
+ def test_Pow():
46
+ assert maple_code(x ** 3) == "x^3"
47
+ assert maple_code(x ** (y ** 3)) == "x^(y^3)"
48
+
49
+ assert maple_code((x ** 3) ** y) == "(x^3)^y"
50
+ assert maple_code(x ** Rational(2, 3)) == 'x^(2/3)'
51
+
52
+ g = implemented_function('g', Lambda(x, 2 * x))
53
+ assert maple_code(1 / (g(x) * 3.5) ** (x - y ** x) / (x ** 2 + y)) == \
54
+ "(3.5*2*x)^(-x + y^x)/(x^2 + y)"
55
+ # For issue 14160
56
+ assert maple_code(Mul(-2, x, Pow(Mul(y, y, evaluate=False), -1, evaluate=False),
57
+ evaluate=False)) == '-2*x/(y*y)'
58
+
59
+
60
+ def test_basic_ops():
61
+ assert maple_code(x * y) == "x*y"
62
+ assert maple_code(x + y) == "x + y"
63
+ assert maple_code(x - y) == "x - y"
64
+ assert maple_code(-x) == "-x"
65
+
66
+
67
+ def test_1_over_x_and_sqrt():
68
+ # 1.0 and 0.5 would do something different in regular StrPrinter,
69
+ # but these are exact in IEEE floating point so no different here.
70
+ assert maple_code(1 / x) == '1/x'
71
+ assert maple_code(x ** -1) == maple_code(x ** -1.0) == '1/x'
72
+ assert maple_code(1 / sqrt(x)) == '1/sqrt(x)'
73
+ assert maple_code(x ** -S.Half) == maple_code(x ** -0.5) == '1/sqrt(x)'
74
+ assert maple_code(sqrt(x)) == 'sqrt(x)'
75
+ assert maple_code(x ** S.Half) == maple_code(x ** 0.5) == 'sqrt(x)'
76
+ assert maple_code(1 / pi) == '1/Pi'
77
+ assert maple_code(pi ** -1) == maple_code(pi ** -1.0) == '1/Pi'
78
+ assert maple_code(pi ** -0.5) == '1/sqrt(Pi)'
79
+
80
+
81
+ def test_mix_number_mult_symbols():
82
+ assert maple_code(3 * x) == "3*x"
83
+ assert maple_code(pi * x) == "Pi*x"
84
+ assert maple_code(3 / x) == "3/x"
85
+ assert maple_code(pi / x) == "Pi/x"
86
+ assert maple_code(x / 3) == '(1/3)*x'
87
+ assert maple_code(x / pi) == "x/Pi"
88
+ assert maple_code(x * y) == "x*y"
89
+ assert maple_code(3 * x * y) == "3*x*y"
90
+ assert maple_code(3 * pi * x * y) == "3*Pi*x*y"
91
+ assert maple_code(x / y) == "x/y"
92
+ assert maple_code(3 * x / y) == "3*x/y"
93
+ assert maple_code(x * y / z) == "x*y/z"
94
+ assert maple_code(x / y * z) == "x*z/y"
95
+ assert maple_code(1 / x / y) == "1/(x*y)"
96
+ assert maple_code(2 * pi * x / y / z) == "2*Pi*x/(y*z)"
97
+ assert maple_code(3 * pi / x) == "3*Pi/x"
98
+ assert maple_code(S(3) / 5) == "3/5"
99
+ assert maple_code(S(3) / 5 * x) == '(3/5)*x'
100
+ assert maple_code(x / y / z) == "x/(y*z)"
101
+ assert maple_code((x + y) / z) == "(x + y)/z"
102
+ assert maple_code((x + y) / (z + x)) == "(x + y)/(x + z)"
103
+ assert maple_code((x + y) / EulerGamma) == '(x + y)/gamma'
104
+ assert maple_code(x / 3 / pi) == '(1/3)*x/Pi'
105
+ assert maple_code(S(3) / 5 * x * y / pi) == '(3/5)*x*y/Pi'
106
+
107
+
108
+ def test_mix_number_pow_symbols():
109
+ assert maple_code(pi ** 3) == 'Pi^3'
110
+ assert maple_code(x ** 2) == 'x^2'
111
+
112
+ assert maple_code(x ** (pi ** 3)) == 'x^(Pi^3)'
113
+ assert maple_code(x ** y) == 'x^y'
114
+
115
+ assert maple_code(x ** (y ** z)) == 'x^(y^z)'
116
+ assert maple_code((x ** y) ** z) == '(x^y)^z'
117
+
118
+
119
+ def test_imag():
120
+ I = S('I')
121
+ assert maple_code(I) == "I"
122
+ assert maple_code(5 * I) == "5*I"
123
+
124
+ assert maple_code((S(3) / 2) * I) == "(3/2)*I"
125
+ assert maple_code(3 + 4 * I) == "3 + 4*I"
126
+
127
+
128
+ def test_constants():
129
+ assert maple_code(pi) == "Pi"
130
+ assert maple_code(oo) == "infinity"
131
+ assert maple_code(-oo) == "-infinity"
132
+ assert maple_code(S.NegativeInfinity) == "-infinity"
133
+ assert maple_code(S.NaN) == "undefined"
134
+ assert maple_code(S.Exp1) == "exp(1)"
135
+ assert maple_code(exp(1)) == "exp(1)"
136
+
137
+
138
+ def test_constants_other():
139
+ assert maple_code(2 * GoldenRatio) == '2*(1/2 + (1/2)*sqrt(5))'
140
+ assert maple_code(2 * Catalan) == '2*Catalan'
141
+ assert maple_code(2 * EulerGamma) == "2*gamma"
142
+
143
+
144
+ def test_boolean():
145
+ assert maple_code(x & y) == "x and y"
146
+ assert maple_code(x | y) == "x or y"
147
+ assert maple_code(~x) == "not x"
148
+ assert maple_code(x & y & z) == "x and y and z"
149
+ assert maple_code(x | y | z) == "x or y or z"
150
+ assert maple_code((x & y) | z) == "z or x and y"
151
+ assert maple_code((x | y) & z) == "z and (x or y)"
152
+
153
+
154
+ def test_Matrices():
155
+ assert maple_code(Matrix(1, 1, [10])) == \
156
+ 'Matrix([[10]], storage = rectangular)'
157
+
158
+ A = Matrix([[1, sin(x / 2), abs(x)],
159
+ [0, 1, pi],
160
+ [0, exp(1), ceiling(x)]])
161
+ expected = \
162
+ 'Matrix(' \
163
+ '[[1, sin((1/2)*x), abs(x)],' \
164
+ ' [0, 1, Pi],' \
165
+ ' [0, exp(1), ceil(x)]], ' \
166
+ 'storage = rectangular)'
167
+ assert maple_code(A) == expected
168
+
169
+ # row and columns
170
+ assert maple_code(A[:, 0]) == \
171
+ 'Matrix([[1], [0], [0]], storage = rectangular)'
172
+ assert maple_code(A[0, :]) == \
173
+ 'Matrix([[1, sin((1/2)*x), abs(x)]], storage = rectangular)'
174
+ assert maple_code(Matrix([[x, x - y, -y]])) == \
175
+ 'Matrix([[x, x - y, -y]], storage = rectangular)'
176
+
177
+ # empty matrices
178
+ assert maple_code(Matrix(0, 0, [])) == \
179
+ 'Matrix([], storage = rectangular)'
180
+ assert maple_code(Matrix(0, 3, [])) == \
181
+ 'Matrix([], storage = rectangular)'
182
+
183
+ def test_SparseMatrices():
184
+ assert maple_code(SparseMatrix(Identity(2))) == 'Matrix([[1, 0], [0, 1]], storage = sparse)'
185
+
186
+
187
+ def test_vector_entries_hadamard():
188
+ # For a row or column, user might to use the other dimension
189
+ A = Matrix([[1, sin(2 / x), 3 * pi / x / 5]])
190
+ assert maple_code(A) == \
191
+ 'Matrix([[1, sin(2/x), (3/5)*Pi/x]], storage = rectangular)'
192
+ assert maple_code(A.T) == \
193
+ 'Matrix([[1], [sin(2/x)], [(3/5)*Pi/x]], storage = rectangular)'
194
+
195
+
196
+ def test_Matrices_entries_not_hadamard():
197
+ A = Matrix([[1, sin(2 / x), 3 * pi / x / 5], [1, 2, x * y]])
198
+ expected = \
199
+ 'Matrix([[1, sin(2/x), (3/5)*Pi/x], [1, 2, x*y]], ' \
200
+ 'storage = rectangular)'
201
+ assert maple_code(A) == expected
202
+
203
+
204
+ def test_MatrixSymbol():
205
+ n = Symbol('n', integer=True)
206
+ A = MatrixSymbol('A', n, n)
207
+ B = MatrixSymbol('B', n, n)
208
+ assert maple_code(A * B) == "A.B"
209
+ assert maple_code(B * A) == "B.A"
210
+ assert maple_code(2 * A * B) == "2*A.B"
211
+ assert maple_code(B * 2 * A) == "2*B.A"
212
+
213
+ assert maple_code(
214
+ A * (B + 3 * Identity(n))) == "A.(3*Matrix(n, shape = identity) + B)"
215
+
216
+ assert maple_code(A ** (x ** 2)) == "MatrixPower(A, x^2)"
217
+ assert maple_code(A ** 3) == "MatrixPower(A, 3)"
218
+ assert maple_code(A ** (S.Half)) == "MatrixPower(A, 1/2)"
219
+
220
+
221
+ def test_special_matrices():
222
+ assert maple_code(6 * Identity(3)) == "6*Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]], storage = sparse)"
223
+ assert maple_code(Identity(x)) == 'Matrix(x, shape = identity)'
224
+
225
+
226
+ def test_containers():
227
+ assert maple_code([1, 2, 3, [4, 5, [6, 7]], 8, [9, 10], 11]) == \
228
+ "[1, 2, 3, [4, 5, [6, 7]], 8, [9, 10], 11]"
229
+
230
+ assert maple_code((1, 2, (3, 4))) == "[1, 2, [3, 4]]"
231
+ assert maple_code([1]) == "[1]"
232
+ assert maple_code((1,)) == "[1]"
233
+ assert maple_code(Tuple(*[1, 2, 3])) == "[1, 2, 3]"
234
+ assert maple_code((1, x * y, (3, x ** 2))) == "[1, x*y, [3, x^2]]"
235
+ # scalar, matrix, empty matrix and empty list
236
+
237
+ assert maple_code((1, eye(3), Matrix(0, 0, []), [])) == \
238
+ "[1, Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]], storage = rectangular), Matrix([], storage = rectangular), []]"
239
+
240
+
241
+ def test_maple_noninline():
242
+ source = maple_code((x + y)/Catalan, assign_to='me', inline=False)
243
+ expected = "me := (x + y)/Catalan"
244
+
245
+ assert source == expected
246
+
247
+
248
+ def test_maple_matrix_assign_to():
249
+ A = Matrix([[1, 2, 3]])
250
+ assert maple_code(A, assign_to='a') == "a := Matrix([[1, 2, 3]], storage = rectangular)"
251
+ A = Matrix([[1, 2], [3, 4]])
252
+ assert maple_code(A, assign_to='A') == "A := Matrix([[1, 2], [3, 4]], storage = rectangular)"
253
+
254
+
255
+ def test_maple_matrix_assign_to_more():
256
+ # assigning to Symbol or MatrixSymbol requires lhs/rhs match
257
+ A = Matrix([[1, 2, 3]])
258
+ B = MatrixSymbol('B', 1, 3)
259
+ C = MatrixSymbol('C', 2, 3)
260
+ assert maple_code(A, assign_to=B) == "B := Matrix([[1, 2, 3]], storage = rectangular)"
261
+ raises(ValueError, lambda: maple_code(A, assign_to=x))
262
+ raises(ValueError, lambda: maple_code(A, assign_to=C))
263
+
264
+
265
+ def test_maple_matrix_1x1():
266
+ A = Matrix([[3]])
267
+ assert maple_code(A, assign_to='B') == "B := Matrix([[3]], storage = rectangular)"
268
+
269
+
270
+ def test_maple_matrix_elements():
271
+ A = Matrix([[x, 2, x * y]])
272
+
273
+ assert maple_code(A[0, 0] ** 2 + A[0, 1] + A[0, 2]) == "x^2 + x*y + 2"
274
+ AA = MatrixSymbol('AA', 1, 3)
275
+ assert maple_code(AA) == "AA"
276
+
277
+ assert maple_code(AA[0, 0] ** 2 + sin(AA[0, 1]) + AA[0, 2]) == \
278
+ "sin(AA[1, 2]) + AA[1, 1]^2 + AA[1, 3]"
279
+ assert maple_code(sum(AA)) == "AA[1, 1] + AA[1, 2] + AA[1, 3]"
280
+
281
+
282
+ def test_maple_boolean():
283
+ assert maple_code(True) == "true"
284
+ assert maple_code(S.true) == "true"
285
+ assert maple_code(False) == "false"
286
+ assert maple_code(S.false) == "false"
287
+
288
+
289
+ def test_sparse():
290
+ M = SparseMatrix(5, 6, {})
291
+ M[2, 2] = 10
292
+ M[1, 2] = 20
293
+ M[1, 3] = 22
294
+ M[0, 3] = 30
295
+ M[3, 0] = x * y
296
+ assert maple_code(M) == \
297
+ 'Matrix([[0, 0, 0, 30, 0, 0],' \
298
+ ' [0, 0, 20, 22, 0, 0],' \
299
+ ' [0, 0, 10, 0, 0, 0],' \
300
+ ' [x*y, 0, 0, 0, 0, 0],' \
301
+ ' [0, 0, 0, 0, 0, 0]], ' \
302
+ 'storage = sparse)'
303
+
304
+ # Not an important point.
305
+ def test_maple_not_supported():
306
+ with raises(NotImplementedError):
307
+ maple_code(S.ComplexInfinity)
308
+
309
+
310
+ def test_MatrixElement_printing():
311
+ # test cases for issue #11821
312
+ A = MatrixSymbol("A", 1, 3)
313
+ B = MatrixSymbol("B", 1, 3)
314
+
315
+ assert (maple_code(A[0, 0]) == "A[1, 1]")
316
+ assert (maple_code(3 * A[0, 0]) == "3*A[1, 1]")
317
+
318
+ F = A-B
319
+
320
+ assert (maple_code(F[0,0]) == "A[1, 1] - B[1, 1]")
321
+
322
+
323
+ def test_hadamard():
324
+ A = MatrixSymbol('A', 3, 3)
325
+ B = MatrixSymbol('B', 3, 3)
326
+ v = MatrixSymbol('v', 3, 1)
327
+ h = MatrixSymbol('h', 1, 3)
328
+ C = HadamardProduct(A, B)
329
+ assert maple_code(C) == "A*B"
330
+
331
+ assert maple_code(C * v) == "(A*B).v"
332
+ # HadamardProduct is higher than dot product.
333
+
334
+ assert maple_code(h * C * v) == "h.(A*B).v"
335
+
336
+ assert maple_code(C * A) == "(A*B).A"
337
+ # mixing Hadamard and scalar strange b/c we vectorize scalars
338
+
339
+ assert maple_code(C * x * y) == "x*y*(A*B)"
340
+
341
+
342
+ def test_maple_piecewise():
343
+ expr = Piecewise((x, x < 1), (x ** 2, True))
344
+
345
+ assert maple_code(expr) == "piecewise(x < 1, x, x^2)"
346
+ assert maple_code(expr, assign_to="r") == (
347
+ "r := piecewise(x < 1, x, x^2)")
348
+
349
+ expr = Piecewise((x ** 2, x < 1), (x ** 3, x < 2), (x ** 4, x < 3), (x ** 5, True))
350
+ expected = "piecewise(x < 1, x^2, x < 2, x^3, x < 3, x^4, x^5)"
351
+ assert maple_code(expr) == expected
352
+ assert maple_code(expr, assign_to="r") == "r := " + expected
353
+
354
+ # Check that Piecewise without a True (default) condition error
355
+ expr = Piecewise((x, x < 1), (x ** 2, x > 1), (sin(x), x > 0))
356
+ raises(ValueError, lambda: maple_code(expr))
357
+
358
+
359
+ def test_maple_piecewise_times_const():
360
+ pw = Piecewise((x, x < 1), (x ** 2, True))
361
+
362
+ assert maple_code(2 * pw) == "2*piecewise(x < 1, x, x^2)"
363
+ assert maple_code(pw / x) == "piecewise(x < 1, x, x^2)/x"
364
+ assert maple_code(pw / (x * y)) == "piecewise(x < 1, x, x^2)/(x*y)"
365
+ assert maple_code(pw / 3) == "(1/3)*piecewise(x < 1, x, x^2)"
366
+
367
+
368
+ def test_maple_derivatives():
369
+ f = Function('f')
370
+ assert maple_code(f(x).diff(x)) == 'diff(f(x), x)'
371
+ assert maple_code(f(x).diff(x, 2)) == 'diff(f(x), x$2)'
372
+
373
+
374
+ def test_automatic_rewrites():
375
+ assert maple_code(lucas(x)) == '(2^(-x)*((1 - sqrt(5))^x + (1 + sqrt(5))^x))'
376
+ assert maple_code(sinc(x)) == '(piecewise(x <> 0, sin(x)/x, 1))'
377
+
378
+
379
+ def test_specfun():
380
+ assert maple_code('asin(x)') == 'arcsin(x)'
381
+ assert maple_code(besseli(x, y)) == 'BesselI(x, y)'
lib/python3.12/site-packages/sympy/printing/tests/test_mathematica.py ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.core import (S, pi, oo, symbols, Function, Rational, Integer, Tuple,
2
+ Derivative, Eq, Ne, Le, Lt, Gt, Ge)
3
+ from sympy.integrals import Integral
4
+ from sympy.concrete import Sum
5
+ from sympy.functions import (exp, sin, cos, fresnelc, fresnels, conjugate, Max,
6
+ Min, gamma, polygamma, loggamma, erf, erfi, erfc,
7
+ erf2, expint, erfinv, erfcinv, Ei, Si, Ci, li,
8
+ Shi, Chi, uppergamma, beta, subfactorial, erf2inv,
9
+ factorial, factorial2, catalan, RisingFactorial,
10
+ FallingFactorial, harmonic, atan2, sec, acsc,
11
+ hermite, laguerre, assoc_laguerre, jacobi,
12
+ gegenbauer, chebyshevt, chebyshevu, legendre,
13
+ assoc_legendre, Li, LambertW)
14
+
15
+ from sympy.printing.mathematica import mathematica_code as mcode
16
+
17
+ x, y, z, w = symbols('x,y,z,w')
18
+ f = Function('f')
19
+
20
+
21
+ def test_Integer():
22
+ assert mcode(Integer(67)) == "67"
23
+ assert mcode(Integer(-1)) == "-1"
24
+
25
+
26
+ def test_Rational():
27
+ assert mcode(Rational(3, 7)) == "3/7"
28
+ assert mcode(Rational(18, 9)) == "2"
29
+ assert mcode(Rational(3, -7)) == "-3/7"
30
+ assert mcode(Rational(-3, -7)) == "3/7"
31
+ assert mcode(x + Rational(3, 7)) == "x + 3/7"
32
+ assert mcode(Rational(3, 7)*x) == "(3/7)*x"
33
+
34
+
35
+ def test_Relational():
36
+ assert mcode(Eq(x, y)) == "x == y"
37
+ assert mcode(Ne(x, y)) == "x != y"
38
+ assert mcode(Le(x, y)) == "x <= y"
39
+ assert mcode(Lt(x, y)) == "x < y"
40
+ assert mcode(Gt(x, y)) == "x > y"
41
+ assert mcode(Ge(x, y)) == "x >= y"
42
+
43
+
44
+ def test_Function():
45
+ assert mcode(f(x, y, z)) == "f[x, y, z]"
46
+ assert mcode(sin(x) ** cos(x)) == "Sin[x]^Cos[x]"
47
+ assert mcode(sec(x) * acsc(x)) == "ArcCsc[x]*Sec[x]"
48
+ assert mcode(atan2(x, y)) == "ArcTan[x, y]"
49
+ assert mcode(conjugate(x)) == "Conjugate[x]"
50
+ assert mcode(Max(x, y, z)*Min(y, z)) == "Max[x, y, z]*Min[y, z]"
51
+ assert mcode(fresnelc(x)) == "FresnelC[x]"
52
+ assert mcode(fresnels(x)) == "FresnelS[x]"
53
+ assert mcode(gamma(x)) == "Gamma[x]"
54
+ assert mcode(uppergamma(x, y)) == "Gamma[x, y]"
55
+ assert mcode(polygamma(x, y)) == "PolyGamma[x, y]"
56
+ assert mcode(loggamma(x)) == "LogGamma[x]"
57
+ assert mcode(erf(x)) == "Erf[x]"
58
+ assert mcode(erfc(x)) == "Erfc[x]"
59
+ assert mcode(erfi(x)) == "Erfi[x]"
60
+ assert mcode(erf2(x, y)) == "Erf[x, y]"
61
+ assert mcode(expint(x, y)) == "ExpIntegralE[x, y]"
62
+ assert mcode(erfcinv(x)) == "InverseErfc[x]"
63
+ assert mcode(erfinv(x)) == "InverseErf[x]"
64
+ assert mcode(erf2inv(x, y)) == "InverseErf[x, y]"
65
+ assert mcode(Ei(x)) == "ExpIntegralEi[x]"
66
+ assert mcode(Ci(x)) == "CosIntegral[x]"
67
+ assert mcode(li(x)) == "LogIntegral[x]"
68
+ assert mcode(Si(x)) == "SinIntegral[x]"
69
+ assert mcode(Shi(x)) == "SinhIntegral[x]"
70
+ assert mcode(Chi(x)) == "CoshIntegral[x]"
71
+ assert mcode(beta(x, y)) == "Beta[x, y]"
72
+ assert mcode(factorial(x)) == "Factorial[x]"
73
+ assert mcode(factorial2(x)) == "Factorial2[x]"
74
+ assert mcode(subfactorial(x)) == "Subfactorial[x]"
75
+ assert mcode(FallingFactorial(x, y)) == "FactorialPower[x, y]"
76
+ assert mcode(RisingFactorial(x, y)) == "Pochhammer[x, y]"
77
+ assert mcode(catalan(x)) == "CatalanNumber[x]"
78
+ assert mcode(harmonic(x)) == "HarmonicNumber[x]"
79
+ assert mcode(harmonic(x, y)) == "HarmonicNumber[x, y]"
80
+ assert mcode(Li(x)) == "LogIntegral[x] - LogIntegral[2]"
81
+ assert mcode(LambertW(x)) == "ProductLog[x]"
82
+ assert mcode(LambertW(x, -1)) == "ProductLog[-1, x]"
83
+ assert mcode(LambertW(x, y)) == "ProductLog[y, x]"
84
+
85
+
86
+ def test_special_polynomials():
87
+ assert mcode(hermite(x, y)) == "HermiteH[x, y]"
88
+ assert mcode(laguerre(x, y)) == "LaguerreL[x, y]"
89
+ assert mcode(assoc_laguerre(x, y, z)) == "LaguerreL[x, y, z]"
90
+ assert mcode(jacobi(x, y, z, w)) == "JacobiP[x, y, z, w]"
91
+ assert mcode(gegenbauer(x, y, z)) == "GegenbauerC[x, y, z]"
92
+ assert mcode(chebyshevt(x, y)) == "ChebyshevT[x, y]"
93
+ assert mcode(chebyshevu(x, y)) == "ChebyshevU[x, y]"
94
+ assert mcode(legendre(x, y)) == "LegendreP[x, y]"
95
+ assert mcode(assoc_legendre(x, y, z)) == "LegendreP[x, y, z]"
96
+
97
+
98
+ def test_Pow():
99
+ assert mcode(x**3) == "x^3"
100
+ assert mcode(x**(y**3)) == "x^(y^3)"
101
+ assert mcode(1/(f(x)*3.5)**(x - y**x)/(x**2 + y)) == \
102
+ "(3.5*f[x])^(-x + y^x)/(x^2 + y)"
103
+ assert mcode(x**-1.0) == 'x^(-1.0)'
104
+ assert mcode(x**Rational(2, 3)) == 'x^(2/3)'
105
+
106
+
107
+ def test_Mul():
108
+ A, B, C, D = symbols('A B C D', commutative=False)
109
+ assert mcode(x*y*z) == "x*y*z"
110
+ assert mcode(x*y*A) == "x*y*A"
111
+ assert mcode(x*y*A*B) == "x*y*A**B"
112
+ assert mcode(x*y*A*B*C) == "x*y*A**B**C"
113
+ assert mcode(x*A*B*(C + D)*A*y) == "x*y*A**B**(C + D)**A"
114
+
115
+
116
+ def test_constants():
117
+ assert mcode(S.Zero) == "0"
118
+ assert mcode(S.One) == "1"
119
+ assert mcode(S.NegativeOne) == "-1"
120
+ assert mcode(S.Half) == "1/2"
121
+ assert mcode(S.ImaginaryUnit) == "I"
122
+
123
+ assert mcode(oo) == "Infinity"
124
+ assert mcode(S.NegativeInfinity) == "-Infinity"
125
+ assert mcode(S.ComplexInfinity) == "ComplexInfinity"
126
+ assert mcode(S.NaN) == "Indeterminate"
127
+
128
+ assert mcode(S.Exp1) == "E"
129
+ assert mcode(pi) == "Pi"
130
+ assert mcode(S.GoldenRatio) == "GoldenRatio"
131
+ assert mcode(S.TribonacciConstant) == \
132
+ "(1/3 + (1/3)*(19 - 3*33^(1/2))^(1/3) + " \
133
+ "(1/3)*(3*33^(1/2) + 19)^(1/3))"
134
+ assert mcode(2*S.TribonacciConstant) == \
135
+ "2*(1/3 + (1/3)*(19 - 3*33^(1/2))^(1/3) + " \
136
+ "(1/3)*(3*33^(1/2) + 19)^(1/3))"
137
+ assert mcode(S.EulerGamma) == "EulerGamma"
138
+ assert mcode(S.Catalan) == "Catalan"
139
+
140
+
141
+ def test_containers():
142
+ assert mcode([1, 2, 3, [4, 5, [6, 7]], 8, [9, 10], 11]) == \
143
+ "{1, 2, 3, {4, 5, {6, 7}}, 8, {9, 10}, 11}"
144
+ assert mcode((1, 2, (3, 4))) == "{1, 2, {3, 4}}"
145
+ assert mcode([1]) == "{1}"
146
+ assert mcode((1,)) == "{1}"
147
+ assert mcode(Tuple(*[1, 2, 3])) == "{1, 2, 3}"
148
+
149
+
150
+ def test_matrices():
151
+ from sympy.matrices import MutableDenseMatrix, MutableSparseMatrix, \
152
+ ImmutableDenseMatrix, ImmutableSparseMatrix
153
+ A = MutableDenseMatrix(
154
+ [[1, -1, 0, 0],
155
+ [0, 1, -1, 0],
156
+ [0, 0, 1, -1],
157
+ [0, 0, 0, 1]]
158
+ )
159
+ B = MutableSparseMatrix(A)
160
+ C = ImmutableDenseMatrix(A)
161
+ D = ImmutableSparseMatrix(A)
162
+
163
+ assert mcode(C) == mcode(A) == \
164
+ "{{1, -1, 0, 0}, " \
165
+ "{0, 1, -1, 0}, " \
166
+ "{0, 0, 1, -1}, " \
167
+ "{0, 0, 0, 1}}"
168
+
169
+ assert mcode(D) == mcode(B) == \
170
+ "SparseArray[{" \
171
+ "{1, 1} -> 1, {1, 2} -> -1, {2, 2} -> 1, {2, 3} -> -1, " \
172
+ "{3, 3} -> 1, {3, 4} -> -1, {4, 4} -> 1" \
173
+ "}, {4, 4}]"
174
+
175
+ # Trivial cases of matrices
176
+ assert mcode(MutableDenseMatrix(0, 0, [])) == '{}'
177
+ assert mcode(MutableSparseMatrix(0, 0, [])) == 'SparseArray[{}, {0, 0}]'
178
+ assert mcode(MutableDenseMatrix(0, 3, [])) == '{}'
179
+ assert mcode(MutableSparseMatrix(0, 3, [])) == 'SparseArray[{}, {0, 3}]'
180
+ assert mcode(MutableDenseMatrix(3, 0, [])) == '{{}, {}, {}}'
181
+ assert mcode(MutableSparseMatrix(3, 0, [])) == 'SparseArray[{}, {3, 0}]'
182
+
183
+ def test_NDArray():
184
+ from sympy.tensor.array import (
185
+ MutableDenseNDimArray, ImmutableDenseNDimArray,
186
+ MutableSparseNDimArray, ImmutableSparseNDimArray)
187
+
188
+ example = MutableDenseNDimArray(
189
+ [[[1, 2, 3, 4],
190
+ [5, 6, 7, 8],
191
+ [9, 10, 11, 12]],
192
+ [[13, 14, 15, 16],
193
+ [17, 18, 19, 20],
194
+ [21, 22, 23, 24]]]
195
+ )
196
+
197
+ assert mcode(example) == \
198
+ "{{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}, " \
199
+ "{{13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}}}"
200
+
201
+ example = ImmutableDenseNDimArray(example)
202
+
203
+ assert mcode(example) == \
204
+ "{{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}, " \
205
+ "{{13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}}}"
206
+
207
+ example = MutableSparseNDimArray(example)
208
+
209
+ assert mcode(example) == \
210
+ "SparseArray[{" \
211
+ "{1, 1, 1} -> 1, {1, 1, 2} -> 2, {1, 1, 3} -> 3, " \
212
+ "{1, 1, 4} -> 4, {1, 2, 1} -> 5, {1, 2, 2} -> 6, " \
213
+ "{1, 2, 3} -> 7, {1, 2, 4} -> 8, {1, 3, 1} -> 9, " \
214
+ "{1, 3, 2} -> 10, {1, 3, 3} -> 11, {1, 3, 4} -> 12, " \
215
+ "{2, 1, 1} -> 13, {2, 1, 2} -> 14, {2, 1, 3} -> 15, " \
216
+ "{2, 1, 4} -> 16, {2, 2, 1} -> 17, {2, 2, 2} -> 18, " \
217
+ "{2, 2, 3} -> 19, {2, 2, 4} -> 20, {2, 3, 1} -> 21, " \
218
+ "{2, 3, 2} -> 22, {2, 3, 3} -> 23, {2, 3, 4} -> 24" \
219
+ "}, {2, 3, 4}]"
220
+
221
+ example = ImmutableSparseNDimArray(example)
222
+
223
+ assert mcode(example) == \
224
+ "SparseArray[{" \
225
+ "{1, 1, 1} -> 1, {1, 1, 2} -> 2, {1, 1, 3} -> 3, " \
226
+ "{1, 1, 4} -> 4, {1, 2, 1} -> 5, {1, 2, 2} -> 6, " \
227
+ "{1, 2, 3} -> 7, {1, 2, 4} -> 8, {1, 3, 1} -> 9, " \
228
+ "{1, 3, 2} -> 10, {1, 3, 3} -> 11, {1, 3, 4} -> 12, " \
229
+ "{2, 1, 1} -> 13, {2, 1, 2} -> 14, {2, 1, 3} -> 15, " \
230
+ "{2, 1, 4} -> 16, {2, 2, 1} -> 17, {2, 2, 2} -> 18, " \
231
+ "{2, 2, 3} -> 19, {2, 2, 4} -> 20, {2, 3, 1} -> 21, " \
232
+ "{2, 3, 2} -> 22, {2, 3, 3} -> 23, {2, 3, 4} -> 24" \
233
+ "}, {2, 3, 4}]"
234
+
235
+
236
+ def test_Integral():
237
+ assert mcode(Integral(sin(sin(x)), x)) == "Hold[Integrate[Sin[Sin[x]], x]]"
238
+ assert mcode(Integral(exp(-x**2 - y**2),
239
+ (x, -oo, oo),
240
+ (y, -oo, oo))) == \
241
+ "Hold[Integrate[Exp[-x^2 - y^2], {x, -Infinity, Infinity}, " \
242
+ "{y, -Infinity, Infinity}]]"
243
+
244
+
245
+ def test_Derivative():
246
+ assert mcode(Derivative(sin(x), x)) == "Hold[D[Sin[x], x]]"
247
+ assert mcode(Derivative(x, x)) == "Hold[D[x, x]]"
248
+ assert mcode(Derivative(sin(x)*y**4, x, 2)) == "Hold[D[y^4*Sin[x], {x, 2}]]"
249
+ assert mcode(Derivative(sin(x)*y**4, x, y, x)) == "Hold[D[y^4*Sin[x], x, y, x]]"
250
+ assert mcode(Derivative(sin(x)*y**4, x, y, 3, x)) == "Hold[D[y^4*Sin[x], x, {y, 3}, x]]"
251
+
252
+
253
+ def test_Sum():
254
+ assert mcode(Sum(sin(x), (x, 0, 10))) == "Hold[Sum[Sin[x], {x, 0, 10}]]"
255
+ assert mcode(Sum(exp(-x**2 - y**2),
256
+ (x, -oo, oo),
257
+ (y, -oo, oo))) == \
258
+ "Hold[Sum[Exp[-x^2 - y^2], {x, -Infinity, Infinity}, " \
259
+ "{y, -Infinity, Infinity}]]"
260
+
261
+
262
+ def test_comment():
263
+ from sympy.printing.mathematica import MCodePrinter
264
+ assert MCodePrinter()._get_comment("Hello World") == \
265
+ "(* Hello World *)"
266
+
267
+
268
+ def test_userfuncs():
269
+ # Dictionary mutation test
270
+ some_function = symbols("some_function", cls=Function)
271
+ my_user_functions = {"some_function": "SomeFunction"}
272
+ assert mcode(
273
+ some_function(z),
274
+ user_functions=my_user_functions) == \
275
+ 'SomeFunction[z]'
276
+ assert mcode(
277
+ some_function(z),
278
+ user_functions=my_user_functions) == \
279
+ 'SomeFunction[z]'
280
+
281
+ # List argument test
282
+ my_user_functions = \
283
+ {"some_function": [(lambda x: True, "SomeOtherFunction")]}
284
+ assert mcode(
285
+ some_function(z),
286
+ user_functions=my_user_functions) == \
287
+ 'SomeOtherFunction[z]'
lib/python3.12/site-packages/sympy/printing/tests/test_octave.py ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.core import (S, pi, oo, symbols, Function, Rational, Integer,
2
+ Tuple, Symbol, EulerGamma, GoldenRatio, Catalan,
3
+ Lambda, Mul, Pow, Mod, Eq, Ne, Le, Lt, Gt, Ge)
4
+ from sympy.codegen.matrix_nodes import MatrixSolve
5
+ from sympy.functions import (arg, atan2, bernoulli, beta, ceiling, chebyshevu,
6
+ chebyshevt, conjugate, DiracDelta, exp, expint,
7
+ factorial, floor, harmonic, Heaviside, im,
8
+ laguerre, LambertW, log, Max, Min, Piecewise,
9
+ polylog, re, RisingFactorial, sign, sinc, sqrt,
10
+ zeta, binomial, legendre, dirichlet_eta,
11
+ riemann_xi)
12
+ from sympy.functions import (sin, cos, tan, cot, sec, csc, asin, acos, acot,
13
+ atan, asec, acsc, sinh, cosh, tanh, coth, csch,
14
+ sech, asinh, acosh, atanh, acoth, asech, acsch)
15
+ from sympy.testing.pytest import raises, XFAIL
16
+ from sympy.utilities.lambdify import implemented_function
17
+ from sympy.matrices import (eye, Matrix, MatrixSymbol, Identity,
18
+ HadamardProduct, SparseMatrix, HadamardPower)
19
+ from sympy.functions.special.bessel import (jn, yn, besselj, bessely, besseli,
20
+ besselk, hankel1, hankel2, airyai,
21
+ airybi, airyaiprime, airybiprime)
22
+ from sympy.functions.special.gamma_functions import (gamma, lowergamma,
23
+ uppergamma, loggamma,
24
+ polygamma)
25
+ from sympy.functions.special.error_functions import (Chi, Ci, erf, erfc, erfi,
26
+ erfcinv, erfinv, fresnelc,
27
+ fresnels, li, Shi, Si, Li,
28
+ erf2, Ei)
29
+ from sympy.printing.octave import octave_code, octave_code as mcode
30
+
31
+ x, y, z = symbols('x,y,z')
32
+
33
+
34
+ def test_Integer():
35
+ assert mcode(Integer(67)) == "67"
36
+ assert mcode(Integer(-1)) == "-1"
37
+
38
+
39
+ def test_Rational():
40
+ assert mcode(Rational(3, 7)) == "3/7"
41
+ assert mcode(Rational(18, 9)) == "2"
42
+ assert mcode(Rational(3, -7)) == "-3/7"
43
+ assert mcode(Rational(-3, -7)) == "3/7"
44
+ assert mcode(x + Rational(3, 7)) == "x + 3/7"
45
+ assert mcode(Rational(3, 7)*x) == "3*x/7"
46
+
47
+
48
+ def test_Relational():
49
+ assert mcode(Eq(x, y)) == "x == y"
50
+ assert mcode(Ne(x, y)) == "x != y"
51
+ assert mcode(Le(x, y)) == "x <= y"
52
+ assert mcode(Lt(x, y)) == "x < y"
53
+ assert mcode(Gt(x, y)) == "x > y"
54
+ assert mcode(Ge(x, y)) == "x >= y"
55
+
56
+
57
+ def test_Function():
58
+ assert mcode(sin(x) ** cos(x)) == "sin(x).^cos(x)"
59
+ assert mcode(sign(x)) == "sign(x)"
60
+ assert mcode(exp(x)) == "exp(x)"
61
+ assert mcode(log(x)) == "log(x)"
62
+ assert mcode(factorial(x)) == "factorial(x)"
63
+ assert mcode(floor(x)) == "floor(x)"
64
+ assert mcode(atan2(y, x)) == "atan2(y, x)"
65
+ assert mcode(beta(x, y)) == 'beta(x, y)'
66
+ assert mcode(polylog(x, y)) == 'polylog(x, y)'
67
+ assert mcode(harmonic(x)) == 'harmonic(x)'
68
+ assert mcode(bernoulli(x)) == "bernoulli(x)"
69
+ assert mcode(bernoulli(x, y)) == "bernoulli(x, y)"
70
+ assert mcode(legendre(x, y)) == "legendre(x, y)"
71
+
72
+
73
+ def test_Function_change_name():
74
+ assert mcode(abs(x)) == "abs(x)"
75
+ assert mcode(ceiling(x)) == "ceil(x)"
76
+ assert mcode(arg(x)) == "angle(x)"
77
+ assert mcode(im(x)) == "imag(x)"
78
+ assert mcode(re(x)) == "real(x)"
79
+ assert mcode(conjugate(x)) == "conj(x)"
80
+ assert mcode(chebyshevt(y, x)) == "chebyshevT(y, x)"
81
+ assert mcode(chebyshevu(y, x)) == "chebyshevU(y, x)"
82
+ assert mcode(laguerre(x, y)) == "laguerreL(x, y)"
83
+ assert mcode(Chi(x)) == "coshint(x)"
84
+ assert mcode(Shi(x)) == "sinhint(x)"
85
+ assert mcode(Ci(x)) == "cosint(x)"
86
+ assert mcode(Si(x)) == "sinint(x)"
87
+ assert mcode(li(x)) == "logint(x)"
88
+ assert mcode(loggamma(x)) == "gammaln(x)"
89
+ assert mcode(polygamma(x, y)) == "psi(x, y)"
90
+ assert mcode(RisingFactorial(x, y)) == "pochhammer(x, y)"
91
+ assert mcode(DiracDelta(x)) == "dirac(x)"
92
+ assert mcode(DiracDelta(x, 3)) == "dirac(3, x)"
93
+ assert mcode(Heaviside(x)) == "heaviside(x, 1/2)"
94
+ assert mcode(Heaviside(x, y)) == "heaviside(x, y)"
95
+ assert mcode(binomial(x, y)) == "bincoeff(x, y)"
96
+ assert mcode(Mod(x, y)) == "mod(x, y)"
97
+
98
+
99
+ def test_minmax():
100
+ assert mcode(Max(x, y) + Min(x, y)) == "max(x, y) + min(x, y)"
101
+ assert mcode(Max(x, y, z)) == "max(x, max(y, z))"
102
+ assert mcode(Min(x, y, z)) == "min(x, min(y, z))"
103
+
104
+
105
+ def test_Pow():
106
+ assert mcode(x**3) == "x.^3"
107
+ assert mcode(x**(y**3)) == "x.^(y.^3)"
108
+ assert mcode(x**Rational(2, 3)) == 'x.^(2/3)'
109
+ g = implemented_function('g', Lambda(x, 2*x))
110
+ assert mcode(1/(g(x)*3.5)**(x - y**x)/(x**2 + y)) == \
111
+ "(3.5*2*x).^(-x + y.^x)./(x.^2 + y)"
112
+ # For issue 14160
113
+ assert mcode(Mul(-2, x, Pow(Mul(y,y,evaluate=False), -1, evaluate=False),
114
+ evaluate=False)) == '-2*x./(y.*y)'
115
+
116
+
117
+ def test_basic_ops():
118
+ assert mcode(x*y) == "x.*y"
119
+ assert mcode(x + y) == "x + y"
120
+ assert mcode(x - y) == "x - y"
121
+ assert mcode(-x) == "-x"
122
+
123
+
124
+ def test_1_over_x_and_sqrt():
125
+ # 1.0 and 0.5 would do something different in regular StrPrinter,
126
+ # but these are exact in IEEE floating point so no different here.
127
+ assert mcode(1/x) == '1./x'
128
+ assert mcode(x**-1) == mcode(x**-1.0) == '1./x'
129
+ assert mcode(1/sqrt(x)) == '1./sqrt(x)'
130
+ assert mcode(x**-S.Half) == mcode(x**-0.5) == '1./sqrt(x)'
131
+ assert mcode(sqrt(x)) == 'sqrt(x)'
132
+ assert mcode(x**S.Half) == mcode(x**0.5) == 'sqrt(x)'
133
+ assert mcode(1/pi) == '1/pi'
134
+ assert mcode(pi**-1) == mcode(pi**-1.0) == '1/pi'
135
+ assert mcode(pi**-0.5) == '1/sqrt(pi)'
136
+
137
+
138
+ def test_mix_number_mult_symbols():
139
+ assert mcode(3*x) == "3*x"
140
+ assert mcode(pi*x) == "pi*x"
141
+ assert mcode(3/x) == "3./x"
142
+ assert mcode(pi/x) == "pi./x"
143
+ assert mcode(x/3) == "x/3"
144
+ assert mcode(x/pi) == "x/pi"
145
+ assert mcode(x*y) == "x.*y"
146
+ assert mcode(3*x*y) == "3*x.*y"
147
+ assert mcode(3*pi*x*y) == "3*pi*x.*y"
148
+ assert mcode(x/y) == "x./y"
149
+ assert mcode(3*x/y) == "3*x./y"
150
+ assert mcode(x*y/z) == "x.*y./z"
151
+ assert mcode(x/y*z) == "x.*z./y"
152
+ assert mcode(1/x/y) == "1./(x.*y)"
153
+ assert mcode(2*pi*x/y/z) == "2*pi*x./(y.*z)"
154
+ assert mcode(3*pi/x) == "3*pi./x"
155
+ assert mcode(S(3)/5) == "3/5"
156
+ assert mcode(S(3)/5*x) == "3*x/5"
157
+ assert mcode(x/y/z) == "x./(y.*z)"
158
+ assert mcode((x+y)/z) == "(x + y)./z"
159
+ assert mcode((x+y)/(z+x)) == "(x + y)./(x + z)"
160
+ assert mcode((x+y)/EulerGamma) == "(x + y)/%s" % EulerGamma.evalf(17)
161
+ assert mcode(x/3/pi) == "x/(3*pi)"
162
+ assert mcode(S(3)/5*x*y/pi) == "3*x.*y/(5*pi)"
163
+
164
+
165
+ def test_mix_number_pow_symbols():
166
+ assert mcode(pi**3) == 'pi^3'
167
+ assert mcode(x**2) == 'x.^2'
168
+ assert mcode(x**(pi**3)) == 'x.^(pi^3)'
169
+ assert mcode(x**y) == 'x.^y'
170
+ assert mcode(x**(y**z)) == 'x.^(y.^z)'
171
+ assert mcode((x**y)**z) == '(x.^y).^z'
172
+
173
+
174
+ def test_imag():
175
+ I = S('I')
176
+ assert mcode(I) == "1i"
177
+ assert mcode(5*I) == "5i"
178
+ assert mcode((S(3)/2)*I) == "3*1i/2"
179
+ assert mcode(3+4*I) == "3 + 4i"
180
+ assert mcode(sqrt(3)*I) == "sqrt(3)*1i"
181
+
182
+
183
+ def test_constants():
184
+ assert mcode(pi) == "pi"
185
+ assert mcode(oo) == "inf"
186
+ assert mcode(-oo) == "-inf"
187
+ assert mcode(S.NegativeInfinity) == "-inf"
188
+ assert mcode(S.NaN) == "NaN"
189
+ assert mcode(S.Exp1) == "exp(1)"
190
+ assert mcode(exp(1)) == "exp(1)"
191
+
192
+
193
+ def test_constants_other():
194
+ assert mcode(2*GoldenRatio) == "2*(1+sqrt(5))/2"
195
+ assert mcode(2*Catalan) == "2*%s" % Catalan.evalf(17)
196
+ assert mcode(2*EulerGamma) == "2*%s" % EulerGamma.evalf(17)
197
+
198
+
199
+ def test_boolean():
200
+ assert mcode(x & y) == "x & y"
201
+ assert mcode(x | y) == "x | y"
202
+ assert mcode(~x) == "~x"
203
+ assert mcode(x & y & z) == "x & y & z"
204
+ assert mcode(x | y | z) == "x | y | z"
205
+ assert mcode((x & y) | z) == "z | x & y"
206
+ assert mcode((x | y) & z) == "z & (x | y)"
207
+
208
+
209
+ def test_KroneckerDelta():
210
+ from sympy.functions import KroneckerDelta
211
+ assert mcode(KroneckerDelta(x, y)) == "double(x == y)"
212
+ assert mcode(KroneckerDelta(x, y + 1)) == "double(x == (y + 1))"
213
+ assert mcode(KroneckerDelta(2**x, y)) == "double((2.^x) == y)"
214
+
215
+
216
+ def test_Matrices():
217
+ assert mcode(Matrix(1, 1, [10])) == "10"
218
+ A = Matrix([[1, sin(x/2), abs(x)],
219
+ [0, 1, pi],
220
+ [0, exp(1), ceiling(x)]]);
221
+ expected = "[1 sin(x/2) abs(x); 0 1 pi; 0 exp(1) ceil(x)]"
222
+ assert mcode(A) == expected
223
+ # row and columns
224
+ assert mcode(A[:,0]) == "[1; 0; 0]"
225
+ assert mcode(A[0,:]) == "[1 sin(x/2) abs(x)]"
226
+ # empty matrices
227
+ assert mcode(Matrix(0, 0, [])) == '[]'
228
+ assert mcode(Matrix(0, 3, [])) == 'zeros(0, 3)'
229
+ # annoying to read but correct
230
+ assert mcode(Matrix([[x, x - y, -y]])) == "[x x - y -y]"
231
+
232
+
233
+ def test_vector_entries_hadamard():
234
+ # For a row or column, user might to use the other dimension
235
+ A = Matrix([[1, sin(2/x), 3*pi/x/5]])
236
+ assert mcode(A) == "[1 sin(2./x) 3*pi./(5*x)]"
237
+ assert mcode(A.T) == "[1; sin(2./x); 3*pi./(5*x)]"
238
+
239
+
240
+ @XFAIL
241
+ def test_Matrices_entries_not_hadamard():
242
+ # For Matrix with col >= 2, row >= 2, they need to be scalars
243
+ # FIXME: is it worth worrying about this? Its not wrong, just
244
+ # leave it user's responsibility to put scalar data for x.
245
+ A = Matrix([[1, sin(2/x), 3*pi/x/5], [1, 2, x*y]])
246
+ expected = ("[1 sin(2/x) 3*pi/(5*x);\n"
247
+ "1 2 x*y]") # <- we give x.*y
248
+ assert mcode(A) == expected
249
+
250
+
251
+ def test_MatrixSymbol():
252
+ n = Symbol('n', integer=True)
253
+ A = MatrixSymbol('A', n, n)
254
+ B = MatrixSymbol('B', n, n)
255
+ assert mcode(A*B) == "A*B"
256
+ assert mcode(B*A) == "B*A"
257
+ assert mcode(2*A*B) == "2*A*B"
258
+ assert mcode(B*2*A) == "2*B*A"
259
+ assert mcode(A*(B + 3*Identity(n))) == "A*(3*eye(n) + B)"
260
+ assert mcode(A**(x**2)) == "A^(x.^2)"
261
+ assert mcode(A**3) == "A^3"
262
+ assert mcode(A**S.Half) == "A^(1/2)"
263
+
264
+
265
+ def test_MatrixSolve():
266
+ n = Symbol('n', integer=True)
267
+ A = MatrixSymbol('A', n, n)
268
+ x = MatrixSymbol('x', n, 1)
269
+ assert mcode(MatrixSolve(A, x)) == "A \\ x"
270
+
271
+ def test_special_matrices():
272
+ assert mcode(6*Identity(3)) == "6*eye(3)"
273
+
274
+
275
+ def test_containers():
276
+ assert mcode([1, 2, 3, [4, 5, [6, 7]], 8, [9, 10], 11]) == \
277
+ "{1, 2, 3, {4, 5, {6, 7}}, 8, {9, 10}, 11}"
278
+ assert mcode((1, 2, (3, 4))) == "{1, 2, {3, 4}}"
279
+ assert mcode([1]) == "{1}"
280
+ assert mcode((1,)) == "{1}"
281
+ assert mcode(Tuple(*[1, 2, 3])) == "{1, 2, 3}"
282
+ assert mcode((1, x*y, (3, x**2))) == "{1, x.*y, {3, x.^2}}"
283
+ # scalar, matrix, empty matrix and empty list
284
+ assert mcode((1, eye(3), Matrix(0, 0, []), [])) == "{1, [1 0 0; 0 1 0; 0 0 1], [], {}}"
285
+
286
+
287
+ def test_octave_noninline():
288
+ source = mcode((x+y)/Catalan, assign_to='me', inline=False)
289
+ expected = (
290
+ "Catalan = %s;\n"
291
+ "me = (x + y)/Catalan;"
292
+ ) % Catalan.evalf(17)
293
+ assert source == expected
294
+
295
+
296
+ def test_octave_piecewise():
297
+ expr = Piecewise((x, x < 1), (x**2, True))
298
+ assert mcode(expr) == "((x < 1).*(x) + (~(x < 1)).*(x.^2))"
299
+ assert mcode(expr, assign_to="r") == (
300
+ "r = ((x < 1).*(x) + (~(x < 1)).*(x.^2));")
301
+ assert mcode(expr, assign_to="r", inline=False) == (
302
+ "if (x < 1)\n"
303
+ " r = x;\n"
304
+ "else\n"
305
+ " r = x.^2;\n"
306
+ "end")
307
+ expr = Piecewise((x**2, x < 1), (x**3, x < 2), (x**4, x < 3), (x**5, True))
308
+ expected = ("((x < 1).*(x.^2) + (~(x < 1)).*( ...\n"
309
+ "(x < 2).*(x.^3) + (~(x < 2)).*( ...\n"
310
+ "(x < 3).*(x.^4) + (~(x < 3)).*(x.^5))))")
311
+ assert mcode(expr) == expected
312
+ assert mcode(expr, assign_to="r") == "r = " + expected + ";"
313
+ assert mcode(expr, assign_to="r", inline=False) == (
314
+ "if (x < 1)\n"
315
+ " r = x.^2;\n"
316
+ "elseif (x < 2)\n"
317
+ " r = x.^3;\n"
318
+ "elseif (x < 3)\n"
319
+ " r = x.^4;\n"
320
+ "else\n"
321
+ " r = x.^5;\n"
322
+ "end")
323
+ # Check that Piecewise without a True (default) condition error
324
+ expr = Piecewise((x, x < 1), (x**2, x > 1), (sin(x), x > 0))
325
+ raises(ValueError, lambda: mcode(expr))
326
+
327
+
328
+ def test_octave_piecewise_times_const():
329
+ pw = Piecewise((x, x < 1), (x**2, True))
330
+ assert mcode(2*pw) == "2*((x < 1).*(x) + (~(x < 1)).*(x.^2))"
331
+ assert mcode(pw/x) == "((x < 1).*(x) + (~(x < 1)).*(x.^2))./x"
332
+ assert mcode(pw/(x*y)) == "((x < 1).*(x) + (~(x < 1)).*(x.^2))./(x.*y)"
333
+ assert mcode(pw/3) == "((x < 1).*(x) + (~(x < 1)).*(x.^2))/3"
334
+
335
+
336
+ def test_octave_matrix_assign_to():
337
+ A = Matrix([[1, 2, 3]])
338
+ assert mcode(A, assign_to='a') == "a = [1 2 3];"
339
+ A = Matrix([[1, 2], [3, 4]])
340
+ assert mcode(A, assign_to='A') == "A = [1 2; 3 4];"
341
+
342
+
343
+ def test_octave_matrix_assign_to_more():
344
+ # assigning to Symbol or MatrixSymbol requires lhs/rhs match
345
+ A = Matrix([[1, 2, 3]])
346
+ B = MatrixSymbol('B', 1, 3)
347
+ C = MatrixSymbol('C', 2, 3)
348
+ assert mcode(A, assign_to=B) == "B = [1 2 3];"
349
+ raises(ValueError, lambda: mcode(A, assign_to=x))
350
+ raises(ValueError, lambda: mcode(A, assign_to=C))
351
+
352
+
353
+ def test_octave_matrix_1x1():
354
+ A = Matrix([[3]])
355
+ B = MatrixSymbol('B', 1, 1)
356
+ C = MatrixSymbol('C', 1, 2)
357
+ assert mcode(A, assign_to=B) == "B = 3;"
358
+ # FIXME?
359
+ #assert mcode(A, assign_to=x) == "x = 3;"
360
+ raises(ValueError, lambda: mcode(A, assign_to=C))
361
+
362
+
363
+ def test_octave_matrix_elements():
364
+ A = Matrix([[x, 2, x*y]])
365
+ assert mcode(A[0, 0]**2 + A[0, 1] + A[0, 2]) == "x.^2 + x.*y + 2"
366
+ A = MatrixSymbol('AA', 1, 3)
367
+ assert mcode(A) == "AA"
368
+ assert mcode(A[0, 0]**2 + sin(A[0,1]) + A[0,2]) == \
369
+ "sin(AA(1, 2)) + AA(1, 1).^2 + AA(1, 3)"
370
+ assert mcode(sum(A)) == "AA(1, 1) + AA(1, 2) + AA(1, 3)"
371
+
372
+
373
+ def test_octave_boolean():
374
+ assert mcode(True) == "true"
375
+ assert mcode(S.true) == "true"
376
+ assert mcode(False) == "false"
377
+ assert mcode(S.false) == "false"
378
+
379
+
380
+ def test_octave_not_supported():
381
+ with raises(NotImplementedError):
382
+ mcode(S.ComplexInfinity)
383
+ f = Function('f')
384
+ assert mcode(f(x).diff(x), strict=False) == (
385
+ "% Not supported in Octave:\n"
386
+ "% Derivative\n"
387
+ "Derivative(f(x), x)"
388
+ )
389
+
390
+
391
+ def test_octave_not_supported_not_on_whitelist():
392
+ from sympy.functions.special.polynomials import assoc_laguerre
393
+ with raises(NotImplementedError):
394
+ mcode(assoc_laguerre(x, y, z))
395
+
396
+
397
+ def test_octave_expint():
398
+ assert mcode(expint(1, x)) == "expint(x)"
399
+ with raises(NotImplementedError):
400
+ mcode(expint(2, x))
401
+ assert mcode(expint(y, x), strict=False) == (
402
+ "% Not supported in Octave:\n"
403
+ "% expint\n"
404
+ "expint(y, x)"
405
+ )
406
+
407
+
408
+ def test_trick_indent_with_end_else_words():
409
+ # words starting with "end" or "else" do not confuse the indenter
410
+ t1 = S('endless');
411
+ t2 = S('elsewhere');
412
+ pw = Piecewise((t1, x < 0), (t2, x <= 1), (1, True))
413
+ assert mcode(pw, inline=False) == (
414
+ "if (x < 0)\n"
415
+ " endless\n"
416
+ "elseif (x <= 1)\n"
417
+ " elsewhere\n"
418
+ "else\n"
419
+ " 1\n"
420
+ "end")
421
+
422
+
423
+ def test_hadamard():
424
+ A = MatrixSymbol('A', 3, 3)
425
+ B = MatrixSymbol('B', 3, 3)
426
+ v = MatrixSymbol('v', 3, 1)
427
+ h = MatrixSymbol('h', 1, 3)
428
+ C = HadamardProduct(A, B)
429
+ n = Symbol('n')
430
+ assert mcode(C) == "A.*B"
431
+ assert mcode(C*v) == "(A.*B)*v"
432
+ assert mcode(h*C*v) == "h*(A.*B)*v"
433
+ assert mcode(C*A) == "(A.*B)*A"
434
+ # mixing Hadamard and scalar strange b/c we vectorize scalars
435
+ assert mcode(C*x*y) == "(x.*y)*(A.*B)"
436
+
437
+ # Testing HadamardPower:
438
+ assert mcode(HadamardPower(A, n)) == "A.**n"
439
+ assert mcode(HadamardPower(A, 1+n)) == "A.**(n + 1)"
440
+ assert mcode(HadamardPower(A*B.T, 1+n)) == "(A*B.T).**(n + 1)"
441
+
442
+
443
+ def test_sparse():
444
+ M = SparseMatrix(5, 6, {})
445
+ M[2, 2] = 10;
446
+ M[1, 2] = 20;
447
+ M[1, 3] = 22;
448
+ M[0, 3] = 30;
449
+ M[3, 0] = x*y;
450
+ assert mcode(M) == (
451
+ "sparse([4 2 3 1 2], [1 3 3 4 4], [x.*y 20 10 30 22], 5, 6)"
452
+ )
453
+
454
+
455
+ def test_sinc():
456
+ assert mcode(sinc(x)) == 'sinc(x/pi)'
457
+ assert mcode(sinc(x + 3)) == 'sinc((x + 3)/pi)'
458
+ assert mcode(sinc(pi*(x + 3))) == 'sinc(x + 3)'
459
+
460
+
461
+ def test_trigfun():
462
+ for f in (sin, cos, tan, cot, sec, csc, asin, acos, acot, atan, asec, acsc,
463
+ sinh, cosh, tanh, coth, csch, sech, asinh, acosh, atanh, acoth,
464
+ asech, acsch):
465
+ assert octave_code(f(x) == f.__name__ + '(x)')
466
+
467
+
468
+ def test_specfun():
469
+ n = Symbol('n')
470
+ for f in [besselj, bessely, besseli, besselk]:
471
+ assert octave_code(f(n, x)) == f.__name__ + '(n, x)'
472
+ for f in (erfc, erfi, erf, erfinv, erfcinv, fresnelc, fresnels, gamma):
473
+ assert octave_code(f(x)) == f.__name__ + '(x)'
474
+ assert octave_code(hankel1(n, x)) == 'besselh(n, 1, x)'
475
+ assert octave_code(hankel2(n, x)) == 'besselh(n, 2, x)'
476
+ assert octave_code(airyai(x)) == 'airy(0, x)'
477
+ assert octave_code(airyaiprime(x)) == 'airy(1, x)'
478
+ assert octave_code(airybi(x)) == 'airy(2, x)'
479
+ assert octave_code(airybiprime(x)) == 'airy(3, x)'
480
+ assert octave_code(uppergamma(n, x)) == '(gammainc(x, n, \'upper\').*gamma(n))'
481
+ assert octave_code(lowergamma(n, x)) == '(gammainc(x, n).*gamma(n))'
482
+ assert octave_code(z**lowergamma(n, x)) == 'z.^(gammainc(x, n).*gamma(n))'
483
+ assert octave_code(jn(n, x)) == 'sqrt(2)*sqrt(pi)*sqrt(1./x).*besselj(n + 1/2, x)/2'
484
+ assert octave_code(yn(n, x)) == 'sqrt(2)*sqrt(pi)*sqrt(1./x).*bessely(n + 1/2, x)/2'
485
+ assert octave_code(LambertW(x)) == 'lambertw(x)'
486
+ assert octave_code(LambertW(x, n)) == 'lambertw(n, x)'
487
+
488
+ # Automatic rewrite
489
+ assert octave_code(Ei(x)) == '(logint(exp(x)))'
490
+ assert octave_code(dirichlet_eta(x)) == '(((x == 1).*(log(2)) + (~(x == 1)).*((1 - 2.^(1 - x)).*zeta(x))))'
491
+ assert octave_code(riemann_xi(x)) == '(pi.^(-x/2).*x.*(x - 1).*gamma(x/2).*zeta(x)/2)'
492
+
493
+
494
+ def test_MatrixElement_printing():
495
+ # test cases for issue #11821
496
+ A = MatrixSymbol("A", 1, 3)
497
+ B = MatrixSymbol("B", 1, 3)
498
+ C = MatrixSymbol("C", 1, 3)
499
+
500
+ assert mcode(A[0, 0]) == "A(1, 1)"
501
+ assert mcode(3 * A[0, 0]) == "3*A(1, 1)"
502
+
503
+ F = C[0, 0].subs(C, A - B)
504
+ assert mcode(F) == "(A - B)(1, 1)"
505
+
506
+
507
+ def test_zeta_printing_issue_14820():
508
+ assert octave_code(zeta(x)) == 'zeta(x)'
509
+ with raises(NotImplementedError):
510
+ octave_code(zeta(x, y))
511
+
512
+
513
+ def test_automatic_rewrite():
514
+ assert octave_code(Li(x)) == '(logint(x) - logint(2))'
515
+ assert octave_code(erf2(x, y)) == '(-erf(x) + erf(y))'
lib/python3.12/site-packages/sympy/printing/tests/test_preview.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from sympy.core.relational import Eq
4
+ from sympy.core.symbol import Symbol
5
+ from sympy.functions.elementary.piecewise import Piecewise
6
+ from sympy.printing.preview import preview
7
+
8
+ from io import BytesIO
9
+
10
+
11
+ def test_preview():
12
+ x = Symbol('x')
13
+ obj = BytesIO()
14
+ try:
15
+ preview(x, output='png', viewer='BytesIO', outputbuffer=obj)
16
+ except RuntimeError:
17
+ pass # latex not installed on CI server
18
+
19
+
20
+ def test_preview_unicode_symbol():
21
+ # issue 9107
22
+ a = Symbol('α')
23
+ obj = BytesIO()
24
+ try:
25
+ preview(a, output='png', viewer='BytesIO', outputbuffer=obj)
26
+ except RuntimeError:
27
+ pass # latex not installed on CI server
28
+
29
+
30
+ def test_preview_latex_construct_in_expr():
31
+ # see PR 9801
32
+ x = Symbol('x')
33
+ pw = Piecewise((1, Eq(x, 0)), (0, True))
34
+ obj = BytesIO()
35
+ try:
36
+ preview(pw, output='png', viewer='BytesIO', outputbuffer=obj)
37
+ except RuntimeError:
38
+ pass # latex not installed on CI server
lib/python3.12/site-packages/sympy/printing/tests/test_pycode.py ADDED
@@ -0,0 +1,429 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.codegen import Assignment
2
+ from sympy.codegen.ast import none
3
+ from sympy.codegen.cfunctions import expm1, log1p
4
+ from sympy.codegen.scipy_nodes import cosm1
5
+ from sympy.codegen.matrix_nodes import MatrixSolve
6
+ from sympy.core import Expr, Mod, symbols, Eq, Le, Gt, zoo, oo, Rational, Pow
7
+ from sympy.core.numbers import pi
8
+ from sympy.core.singleton import S
9
+ from sympy.functions import acos, KroneckerDelta, Piecewise, sign, sqrt, Min, Max, cot, acsch, asec, coth, sec
10
+ from sympy.logic import And, Or
11
+ from sympy.matrices import SparseMatrix, MatrixSymbol, Identity
12
+ from sympy.printing.pycode import (
13
+ MpmathPrinter, PythonCodePrinter, pycode, SymPyPrinter
14
+ )
15
+ from sympy.printing.tensorflow import TensorflowPrinter
16
+ from sympy.printing.numpy import NumPyPrinter, SciPyPrinter
17
+ from sympy.testing.pytest import raises, skip
18
+ from sympy.tensor import IndexedBase, Idx
19
+ from sympy.tensor.array.expressions.array_expressions import ArraySymbol, ArrayDiagonal, ArrayContraction, ZeroArray, OneArray
20
+ from sympy.external import import_module
21
+ from sympy.functions.special.gamma_functions import loggamma
22
+
23
+
24
+ x, y, z = symbols('x y z')
25
+ p = IndexedBase("p")
26
+
27
+
28
+ def test_PythonCodePrinter():
29
+ prntr = PythonCodePrinter()
30
+
31
+ assert not prntr.module_imports
32
+
33
+ assert prntr.doprint(x**y) == 'x**y'
34
+ assert prntr.doprint(Mod(x, 2)) == 'x % 2'
35
+ assert prntr.doprint(-Mod(x, y)) == '-(x % y)'
36
+ assert prntr.doprint(Mod(-x, y)) == '(-x) % y'
37
+ assert prntr.doprint(And(x, y)) == 'x and y'
38
+ assert prntr.doprint(Or(x, y)) == 'x or y'
39
+ assert prntr.doprint(1/(x+y)) == '1/(x + y)'
40
+ assert not prntr.module_imports
41
+
42
+ assert prntr.doprint(pi) == 'math.pi'
43
+ assert prntr.module_imports == {'math': {'pi'}}
44
+
45
+ assert prntr.doprint(x**Rational(1, 2)) == 'math.sqrt(x)'
46
+ assert prntr.doprint(sqrt(x)) == 'math.sqrt(x)'
47
+ assert prntr.module_imports == {'math': {'pi', 'sqrt'}}
48
+
49
+ assert prntr.doprint(acos(x)) == 'math.acos(x)'
50
+ assert prntr.doprint(cot(x)) == '(1/math.tan(x))'
51
+ assert prntr.doprint(coth(x)) == '((math.exp(x) + math.exp(-x))/(math.exp(x) - math.exp(-x)))'
52
+ assert prntr.doprint(asec(x)) == '(math.acos(1/x))'
53
+ assert prntr.doprint(acsch(x)) == '(math.log(math.sqrt(1 + x**(-2)) + 1/x))'
54
+
55
+ assert prntr.doprint(Assignment(x, 2)) == 'x = 2'
56
+ assert prntr.doprint(Piecewise((1, Eq(x, 0)),
57
+ (2, x>6))) == '((1) if (x == 0) else (2) if (x > 6) else None)'
58
+ assert prntr.doprint(Piecewise((2, Le(x, 0)),
59
+ (3, Gt(x, 0)), evaluate=False)) == '((2) if (x <= 0) else'\
60
+ ' (3) if (x > 0) else None)'
61
+ assert prntr.doprint(sign(x)) == '(0.0 if x == 0 else math.copysign(1, x))'
62
+ assert prntr.doprint(p[0, 1]) == 'p[0, 1]'
63
+ assert prntr.doprint(KroneckerDelta(x,y)) == '(1 if x == y else 0)'
64
+
65
+ assert prntr.doprint((2,3)) == "(2, 3)"
66
+ assert prntr.doprint([2,3]) == "[2, 3]"
67
+
68
+ assert prntr.doprint(Min(x, y)) == "min(x, y)"
69
+ assert prntr.doprint(Max(x, y)) == "max(x, y)"
70
+
71
+
72
+ def test_PythonCodePrinter_standard():
73
+ prntr = PythonCodePrinter()
74
+
75
+ assert prntr.standard == 'python3'
76
+
77
+ raises(ValueError, lambda: PythonCodePrinter({'standard':'python4'}))
78
+
79
+
80
+ def test_MpmathPrinter():
81
+ p = MpmathPrinter()
82
+ assert p.doprint(sign(x)) == 'mpmath.sign(x)'
83
+ assert p.doprint(Rational(1, 2)) == 'mpmath.mpf(1)/mpmath.mpf(2)'
84
+
85
+ assert p.doprint(S.Exp1) == 'mpmath.e'
86
+ assert p.doprint(S.Pi) == 'mpmath.pi'
87
+ assert p.doprint(S.GoldenRatio) == 'mpmath.phi'
88
+ assert p.doprint(S.EulerGamma) == 'mpmath.euler'
89
+ assert p.doprint(S.NaN) == 'mpmath.nan'
90
+ assert p.doprint(S.Infinity) == 'mpmath.inf'
91
+ assert p.doprint(S.NegativeInfinity) == 'mpmath.ninf'
92
+ assert p.doprint(loggamma(x)) == 'mpmath.loggamma(x)'
93
+
94
+
95
+ def test_NumPyPrinter():
96
+ from sympy.core.function import Lambda
97
+ from sympy.matrices.expressions.adjoint import Adjoint
98
+ from sympy.matrices.expressions.diagonal import (DiagMatrix, DiagonalMatrix, DiagonalOf)
99
+ from sympy.matrices.expressions.funcmatrix import FunctionMatrix
100
+ from sympy.matrices.expressions.hadamard import HadamardProduct
101
+ from sympy.matrices.expressions.kronecker import KroneckerProduct
102
+ from sympy.matrices.expressions.special import (OneMatrix, ZeroMatrix)
103
+ from sympy.abc import a, b
104
+ p = NumPyPrinter()
105
+ assert p.doprint(sign(x)) == 'numpy.sign(x)'
106
+ A = MatrixSymbol("A", 2, 2)
107
+ B = MatrixSymbol("B", 2, 2)
108
+ C = MatrixSymbol("C", 1, 5)
109
+ D = MatrixSymbol("D", 3, 4)
110
+ assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)"
111
+ assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)"
112
+ assert p.doprint(Identity(3)) == "numpy.eye(3)"
113
+
114
+ u = MatrixSymbol('x', 2, 1)
115
+ v = MatrixSymbol('y', 2, 1)
116
+ assert p.doprint(MatrixSolve(A, u)) == 'numpy.linalg.solve(A, x)'
117
+ assert p.doprint(MatrixSolve(A, u) + v) == 'numpy.linalg.solve(A, x) + y'
118
+
119
+ assert p.doprint(ZeroMatrix(2, 3)) == "numpy.zeros((2, 3))"
120
+ assert p.doprint(OneMatrix(2, 3)) == "numpy.ones((2, 3))"
121
+ assert p.doprint(FunctionMatrix(4, 5, Lambda((a, b), a + b))) == \
122
+ "numpy.fromfunction(lambda a, b: a + b, (4, 5))"
123
+ assert p.doprint(HadamardProduct(A, B)) == "numpy.multiply(A, B)"
124
+ assert p.doprint(KroneckerProduct(A, B)) == "numpy.kron(A, B)"
125
+ assert p.doprint(Adjoint(A)) == "numpy.conjugate(numpy.transpose(A))"
126
+ assert p.doprint(DiagonalOf(A)) == "numpy.reshape(numpy.diag(A), (-1, 1))"
127
+ assert p.doprint(DiagMatrix(C)) == "numpy.diagflat(C)"
128
+ assert p.doprint(DiagonalMatrix(D)) == "numpy.multiply(D, numpy.eye(3, 4))"
129
+
130
+ # Workaround for numpy negative integer power errors
131
+ assert p.doprint(x**-1) == 'x**(-1.0)'
132
+ assert p.doprint(x**-2) == 'x**(-2.0)'
133
+
134
+ expr = Pow(2, -1, evaluate=False)
135
+ assert p.doprint(expr) == "2**(-1.0)"
136
+
137
+ assert p.doprint(S.Exp1) == 'numpy.e'
138
+ assert p.doprint(S.Pi) == 'numpy.pi'
139
+ assert p.doprint(S.EulerGamma) == 'numpy.euler_gamma'
140
+ assert p.doprint(S.NaN) == 'numpy.nan'
141
+ assert p.doprint(S.Infinity) == 'numpy.inf'
142
+ assert p.doprint(S.NegativeInfinity) == '-numpy.inf'
143
+
144
+ # Function rewriting operator precedence fix
145
+ assert p.doprint(sec(x)**2) == '(numpy.cos(x)**(-1.0))**2'
146
+
147
+
148
+ def test_issue_18770():
149
+ numpy = import_module('numpy')
150
+ if not numpy:
151
+ skip("numpy not installed.")
152
+
153
+ from sympy.functions.elementary.miscellaneous import (Max, Min)
154
+ from sympy.utilities.lambdify import lambdify
155
+
156
+ expr1 = Min(0.1*x + 3, x + 1, 0.5*x + 1)
157
+ func = lambdify(x, expr1, "numpy")
158
+ assert (func(numpy.linspace(0, 3, 3)) == [1.0, 1.75, 2.5 ]).all()
159
+ assert func(4) == 3
160
+
161
+ expr1 = Max(x**2, x**3)
162
+ func = lambdify(x,expr1, "numpy")
163
+ assert (func(numpy.linspace(-1, 2, 4)) == [1, 0, 1, 8] ).all()
164
+ assert func(4) == 64
165
+
166
+
167
+ def test_SciPyPrinter():
168
+ p = SciPyPrinter()
169
+ expr = acos(x)
170
+ assert 'numpy' not in p.module_imports
171
+ assert p.doprint(expr) == 'numpy.arccos(x)'
172
+ assert 'numpy' in p.module_imports
173
+ assert not any(m.startswith('scipy') for m in p.module_imports)
174
+ smat = SparseMatrix(2, 5, {(0, 1): 3})
175
+ assert p.doprint(smat) == \
176
+ 'scipy.sparse.coo_matrix(([3], ([0], [1])), shape=(2, 5))'
177
+ assert 'scipy.sparse' in p.module_imports
178
+
179
+ assert p.doprint(S.GoldenRatio) == 'scipy.constants.golden_ratio'
180
+ assert p.doprint(S.Pi) == 'scipy.constants.pi'
181
+ assert p.doprint(S.Exp1) == 'numpy.e'
182
+
183
+
184
+ def test_pycode_reserved_words():
185
+ s1, s2 = symbols('if else')
186
+ raises(ValueError, lambda: pycode(s1 + s2, error_on_reserved=True))
187
+ py_str = pycode(s1 + s2)
188
+ assert py_str in ('else_ + if_', 'if_ + else_')
189
+
190
+
191
+ def test_issue_20762():
192
+ # Make sure pycode removes curly braces from subscripted variables
193
+ a_b, b, a_11 = symbols('a_{b} b a_{11}')
194
+ expr = a_b*b
195
+ assert pycode(expr) == 'a_b*b'
196
+ expr = a_11*b
197
+ assert pycode(expr) == 'a_11*b'
198
+
199
+
200
+ def test_sqrt():
201
+ prntr = PythonCodePrinter()
202
+ assert prntr._print_Pow(sqrt(x), rational=False) == 'math.sqrt(x)'
203
+ assert prntr._print_Pow(1/sqrt(x), rational=False) == '1/math.sqrt(x)'
204
+
205
+ prntr = PythonCodePrinter({'standard' : 'python3'})
206
+ assert prntr._print_Pow(sqrt(x), rational=True) == 'x**(1/2)'
207
+ assert prntr._print_Pow(1/sqrt(x), rational=True) == 'x**(-1/2)'
208
+
209
+ prntr = MpmathPrinter()
210
+ assert prntr._print_Pow(sqrt(x), rational=False) == 'mpmath.sqrt(x)'
211
+ assert prntr._print_Pow(sqrt(x), rational=True) == \
212
+ "x**(mpmath.mpf(1)/mpmath.mpf(2))"
213
+
214
+ prntr = NumPyPrinter()
215
+ assert prntr._print_Pow(sqrt(x), rational=False) == 'numpy.sqrt(x)'
216
+ assert prntr._print_Pow(sqrt(x), rational=True) == 'x**(1/2)'
217
+
218
+ prntr = SciPyPrinter()
219
+ assert prntr._print_Pow(sqrt(x), rational=False) == 'numpy.sqrt(x)'
220
+ assert prntr._print_Pow(sqrt(x), rational=True) == 'x**(1/2)'
221
+
222
+ prntr = SymPyPrinter()
223
+ assert prntr._print_Pow(sqrt(x), rational=False) == 'sympy.sqrt(x)'
224
+ assert prntr._print_Pow(sqrt(x), rational=True) == 'x**(1/2)'
225
+
226
+
227
+ def test_frac():
228
+ from sympy.functions.elementary.integers import frac
229
+
230
+ expr = frac(x)
231
+ prntr = NumPyPrinter()
232
+ assert prntr.doprint(expr) == 'numpy.mod(x, 1)'
233
+
234
+ prntr = SciPyPrinter()
235
+ assert prntr.doprint(expr) == 'numpy.mod(x, 1)'
236
+
237
+ prntr = PythonCodePrinter()
238
+ assert prntr.doprint(expr) == 'x % 1'
239
+
240
+ prntr = MpmathPrinter()
241
+ assert prntr.doprint(expr) == 'mpmath.frac(x)'
242
+
243
+ prntr = SymPyPrinter()
244
+ assert prntr.doprint(expr) == 'sympy.functions.elementary.integers.frac(x)'
245
+
246
+
247
+ class CustomPrintedObject(Expr):
248
+ def _numpycode(self, printer):
249
+ return 'numpy'
250
+
251
+ def _mpmathcode(self, printer):
252
+ return 'mpmath'
253
+
254
+
255
+ def test_printmethod():
256
+ obj = CustomPrintedObject()
257
+ assert NumPyPrinter().doprint(obj) == 'numpy'
258
+ assert MpmathPrinter().doprint(obj) == 'mpmath'
259
+
260
+
261
+ def test_codegen_ast_nodes():
262
+ assert pycode(none) == 'None'
263
+
264
+
265
+ def test_issue_14283():
266
+ prntr = PythonCodePrinter()
267
+
268
+ assert prntr.doprint(zoo) == "math.nan"
269
+ assert prntr.doprint(-oo) == "float('-inf')"
270
+
271
+
272
+ def test_NumPyPrinter_print_seq():
273
+ n = NumPyPrinter()
274
+
275
+ assert n._print_seq(range(2)) == '(0, 1,)'
276
+
277
+
278
+ def test_issue_16535_16536():
279
+ from sympy.functions.special.gamma_functions import (lowergamma, uppergamma)
280
+
281
+ a = symbols('a')
282
+ expr1 = lowergamma(a, x)
283
+ expr2 = uppergamma(a, x)
284
+
285
+ prntr = SciPyPrinter()
286
+ assert prntr.doprint(expr1) == 'scipy.special.gamma(a)*scipy.special.gammainc(a, x)'
287
+ assert prntr.doprint(expr2) == 'scipy.special.gamma(a)*scipy.special.gammaincc(a, x)'
288
+
289
+ p_numpy = NumPyPrinter()
290
+ p_pycode = PythonCodePrinter({'strict': False})
291
+
292
+ for expr in [expr1, expr2]:
293
+ with raises(NotImplementedError):
294
+ p_numpy.doprint(expr1)
295
+ assert "Not supported" in p_pycode.doprint(expr)
296
+
297
+
298
+ def test_Integral():
299
+ from sympy.functions.elementary.exponential import exp
300
+ from sympy.integrals.integrals import Integral
301
+
302
+ single = Integral(exp(-x), (x, 0, oo))
303
+ double = Integral(x**2*exp(x*y), (x, -z, z), (y, 0, z))
304
+ indefinite = Integral(x**2, x)
305
+ evaluateat = Integral(x**2, (x, 1))
306
+
307
+ prntr = SciPyPrinter()
308
+ assert prntr.doprint(single) == 'scipy.integrate.quad(lambda x: numpy.exp(-x), 0, numpy.inf)[0]'
309
+ assert prntr.doprint(double) == 'scipy.integrate.nquad(lambda x, y: x**2*numpy.exp(x*y), ((-z, z), (0, z)))[0]'
310
+ raises(NotImplementedError, lambda: prntr.doprint(indefinite))
311
+ raises(NotImplementedError, lambda: prntr.doprint(evaluateat))
312
+
313
+ prntr = MpmathPrinter()
314
+ assert prntr.doprint(single) == 'mpmath.quad(lambda x: mpmath.exp(-x), (0, mpmath.inf))'
315
+ assert prntr.doprint(double) == 'mpmath.quad(lambda x, y: x**2*mpmath.exp(x*y), (-z, z), (0, z))'
316
+ raises(NotImplementedError, lambda: prntr.doprint(indefinite))
317
+ raises(NotImplementedError, lambda: prntr.doprint(evaluateat))
318
+
319
+
320
+ def test_fresnel_integrals():
321
+ from sympy.functions.special.error_functions import (fresnelc, fresnels)
322
+
323
+ expr1 = fresnelc(x)
324
+ expr2 = fresnels(x)
325
+
326
+ prntr = SciPyPrinter()
327
+ assert prntr.doprint(expr1) == 'scipy.special.fresnel(x)[1]'
328
+ assert prntr.doprint(expr2) == 'scipy.special.fresnel(x)[0]'
329
+
330
+ p_numpy = NumPyPrinter()
331
+ p_pycode = PythonCodePrinter()
332
+ p_mpmath = MpmathPrinter()
333
+ for expr in [expr1, expr2]:
334
+ with raises(NotImplementedError):
335
+ p_numpy.doprint(expr)
336
+ with raises(NotImplementedError):
337
+ p_pycode.doprint(expr)
338
+
339
+ assert p_mpmath.doprint(expr1) == 'mpmath.fresnelc(x)'
340
+ assert p_mpmath.doprint(expr2) == 'mpmath.fresnels(x)'
341
+
342
+
343
+ def test_beta():
344
+ from sympy.functions.special.beta_functions import beta
345
+
346
+ expr = beta(x, y)
347
+
348
+ prntr = SciPyPrinter()
349
+ assert prntr.doprint(expr) == 'scipy.special.beta(x, y)'
350
+
351
+ prntr = NumPyPrinter()
352
+ assert prntr.doprint(expr) == '(math.gamma(x)*math.gamma(y)/math.gamma(x + y))'
353
+
354
+ prntr = PythonCodePrinter()
355
+ assert prntr.doprint(expr) == '(math.gamma(x)*math.gamma(y)/math.gamma(x + y))'
356
+
357
+ prntr = PythonCodePrinter({'allow_unknown_functions': True})
358
+ assert prntr.doprint(expr) == '(math.gamma(x)*math.gamma(y)/math.gamma(x + y))'
359
+
360
+ prntr = MpmathPrinter()
361
+ assert prntr.doprint(expr) == 'mpmath.beta(x, y)'
362
+
363
+ def test_airy():
364
+ from sympy.functions.special.bessel import (airyai, airybi)
365
+
366
+ expr1 = airyai(x)
367
+ expr2 = airybi(x)
368
+
369
+ prntr = SciPyPrinter()
370
+ assert prntr.doprint(expr1) == 'scipy.special.airy(x)[0]'
371
+ assert prntr.doprint(expr2) == 'scipy.special.airy(x)[2]'
372
+
373
+ prntr = NumPyPrinter({'strict': False})
374
+ assert "Not supported" in prntr.doprint(expr1)
375
+ assert "Not supported" in prntr.doprint(expr2)
376
+
377
+ prntr = PythonCodePrinter({'strict': False})
378
+ assert "Not supported" in prntr.doprint(expr1)
379
+ assert "Not supported" in prntr.doprint(expr2)
380
+
381
+ def test_airy_prime():
382
+ from sympy.functions.special.bessel import (airyaiprime, airybiprime)
383
+
384
+ expr1 = airyaiprime(x)
385
+ expr2 = airybiprime(x)
386
+
387
+ prntr = SciPyPrinter()
388
+ assert prntr.doprint(expr1) == 'scipy.special.airy(x)[1]'
389
+ assert prntr.doprint(expr2) == 'scipy.special.airy(x)[3]'
390
+
391
+ prntr = NumPyPrinter({'strict': False})
392
+ assert "Not supported" in prntr.doprint(expr1)
393
+ assert "Not supported" in prntr.doprint(expr2)
394
+
395
+ prntr = PythonCodePrinter({'strict': False})
396
+ assert "Not supported" in prntr.doprint(expr1)
397
+ assert "Not supported" in prntr.doprint(expr2)
398
+
399
+
400
+ def test_numerical_accuracy_functions():
401
+ prntr = SciPyPrinter()
402
+ assert prntr.doprint(expm1(x)) == 'numpy.expm1(x)'
403
+ assert prntr.doprint(log1p(x)) == 'numpy.log1p(x)'
404
+ assert prntr.doprint(cosm1(x)) == 'scipy.special.cosm1(x)'
405
+
406
+ def test_array_printer():
407
+ A = ArraySymbol('A', (4,4,6,6,6))
408
+ I = IndexedBase('I')
409
+ i,j,k = Idx('i', (0,1)), Idx('j', (2,3)), Idx('k', (4,5))
410
+
411
+ prntr = NumPyPrinter()
412
+ assert prntr.doprint(ZeroArray(5)) == 'numpy.zeros((5,))'
413
+ assert prntr.doprint(OneArray(5)) == 'numpy.ones((5,))'
414
+ assert prntr.doprint(ArrayContraction(A, [2,3])) == 'numpy.einsum("abccd->abd", A)'
415
+ assert prntr.doprint(I) == 'I'
416
+ assert prntr.doprint(ArrayDiagonal(A, [2,3,4])) == 'numpy.einsum("abccc->abc", A)'
417
+ assert prntr.doprint(ArrayDiagonal(A, [0,1], [2,3])) == 'numpy.einsum("aabbc->cab", A)'
418
+ assert prntr.doprint(ArrayContraction(A, [2], [3])) == 'numpy.einsum("abcde->abe", A)'
419
+ assert prntr.doprint(Assignment(I[i,j,k], I[i,j,k])) == 'I = I'
420
+
421
+ prntr = TensorflowPrinter()
422
+ assert prntr.doprint(ZeroArray(5)) == 'tensorflow.zeros((5,))'
423
+ assert prntr.doprint(OneArray(5)) == 'tensorflow.ones((5,))'
424
+ assert prntr.doprint(ArrayContraction(A, [2,3])) == 'tensorflow.linalg.einsum("abccd->abd", A)'
425
+ assert prntr.doprint(I) == 'I'
426
+ assert prntr.doprint(ArrayDiagonal(A, [2,3,4])) == 'tensorflow.linalg.einsum("abccc->abc", A)'
427
+ assert prntr.doprint(ArrayDiagonal(A, [0,1], [2,3])) == 'tensorflow.linalg.einsum("aabbc->cab", A)'
428
+ assert prntr.doprint(ArrayContraction(A, [2], [3])) == 'tensorflow.linalg.einsum("abcde->abe", A)'
429
+ assert prntr.doprint(Assignment(I[i,j,k], I[i,j,k])) == 'I = I'
lib/python3.12/site-packages/sympy/printing/tests/test_repr.py ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ from typing import Any
3
+
4
+ from sympy.external.gmpy import GROUND_TYPES
5
+ from sympy.testing.pytest import raises, warns_deprecated_sympy
6
+ from sympy.assumptions.ask import Q
7
+ from sympy.core.function import (Function, WildFunction)
8
+ from sympy.core.numbers import (AlgebraicNumber, Float, Integer, Rational)
9
+ from sympy.core.singleton import S
10
+ from sympy.core.symbol import (Dummy, Symbol, Wild, symbols)
11
+ from sympy.core.sympify import sympify
12
+ from sympy.functions.elementary.complexes import Abs
13
+ from sympy.functions.elementary.miscellaneous import (root, sqrt)
14
+ from sympy.functions.elementary.trigonometric import sin
15
+ from sympy.functions.special.delta_functions import Heaviside
16
+ from sympy.logic.boolalg import (false, true)
17
+ from sympy.matrices.dense import (Matrix, ones)
18
+ from sympy.matrices.expressions.matexpr import MatrixSymbol
19
+ from sympy.matrices.immutable import ImmutableDenseMatrix
20
+ from sympy.combinatorics import Cycle, Permutation
21
+ from sympy.core.symbol import Str
22
+ from sympy.geometry import Point, Ellipse
23
+ from sympy.printing import srepr
24
+ from sympy.polys import ring, field, ZZ, QQ, lex, grlex, Poly
25
+ from sympy.polys.polyclasses import DMP
26
+ from sympy.polys.agca.extensions import FiniteExtension
27
+
28
+ x, y = symbols('x,y')
29
+
30
+ # eval(srepr(expr)) == expr has to succeed in the right environment. The right
31
+ # environment is the scope of "from sympy import *" for most cases.
32
+ ENV: dict[str, Any] = {"Str": Str}
33
+ exec("from sympy import *", ENV)
34
+
35
+
36
+ def sT(expr, string, import_stmt=None, **kwargs):
37
+ """
38
+ sT := sreprTest
39
+
40
+ Tests that srepr delivers the expected string and that
41
+ the condition eval(srepr(expr))==expr holds.
42
+ """
43
+ if import_stmt is None:
44
+ ENV2 = ENV
45
+ else:
46
+ ENV2 = ENV.copy()
47
+ exec(import_stmt, ENV2)
48
+
49
+ assert srepr(expr, **kwargs) == string
50
+ assert eval(string, ENV2) == expr
51
+
52
+
53
+ def test_printmethod():
54
+ class R(Abs):
55
+ def _sympyrepr(self, printer):
56
+ return "foo(%s)" % printer._print(self.args[0])
57
+ assert srepr(R(x)) == "foo(Symbol('x'))"
58
+
59
+
60
+ def test_Add():
61
+ sT(x + y, "Add(Symbol('x'), Symbol('y'))")
62
+ assert srepr(x**2 + 1, order='lex') == "Add(Pow(Symbol('x'), Integer(2)), Integer(1))"
63
+ assert srepr(x**2 + 1, order='old') == "Add(Integer(1), Pow(Symbol('x'), Integer(2)))"
64
+ assert srepr(sympify('x + 3 - 2', evaluate=False), order='none') == "Add(Symbol('x'), Integer(3), Mul(Integer(-1), Integer(2)))"
65
+
66
+
67
+ def test_more_than_255_args_issue_10259():
68
+ from sympy.core.add import Add
69
+ from sympy.core.mul import Mul
70
+ for op in (Add, Mul):
71
+ expr = op(*symbols('x:256'))
72
+ assert eval(srepr(expr)) == expr
73
+
74
+
75
+ def test_Function():
76
+ sT(Function("f")(x), "Function('f')(Symbol('x'))")
77
+ # test unapplied Function
78
+ sT(Function('f'), "Function('f')")
79
+
80
+ sT(sin(x), "sin(Symbol('x'))")
81
+ sT(sin, "sin")
82
+
83
+
84
+ def test_Heaviside():
85
+ sT(Heaviside(x), "Heaviside(Symbol('x'))")
86
+ sT(Heaviside(x, 1), "Heaviside(Symbol('x'), Integer(1))")
87
+
88
+
89
+ def test_Geometry():
90
+ sT(Point(0, 0), "Point2D(Integer(0), Integer(0))")
91
+ sT(Ellipse(Point(0, 0), 5, 1),
92
+ "Ellipse(Point2D(Integer(0), Integer(0)), Integer(5), Integer(1))")
93
+ # TODO more tests
94
+
95
+
96
+ def test_Singletons():
97
+ sT(S.Catalan, 'Catalan')
98
+ sT(S.ComplexInfinity, 'zoo')
99
+ sT(S.EulerGamma, 'EulerGamma')
100
+ sT(S.Exp1, 'E')
101
+ sT(S.GoldenRatio, 'GoldenRatio')
102
+ sT(S.TribonacciConstant, 'TribonacciConstant')
103
+ sT(S.Half, 'Rational(1, 2)')
104
+ sT(S.ImaginaryUnit, 'I')
105
+ sT(S.Infinity, 'oo')
106
+ sT(S.NaN, 'nan')
107
+ sT(S.NegativeInfinity, '-oo')
108
+ sT(S.NegativeOne, 'Integer(-1)')
109
+ sT(S.One, 'Integer(1)')
110
+ sT(S.Pi, 'pi')
111
+ sT(S.Zero, 'Integer(0)')
112
+ sT(S.Complexes, 'Complexes')
113
+ sT(S.EmptySequence, 'EmptySequence')
114
+ sT(S.EmptySet, 'EmptySet')
115
+ # sT(S.IdentityFunction, 'Lambda(_x, _x)')
116
+ sT(S.Naturals, 'Naturals')
117
+ sT(S.Naturals0, 'Naturals0')
118
+ sT(S.Rationals, 'Rationals')
119
+ sT(S.Reals, 'Reals')
120
+ sT(S.UniversalSet, 'UniversalSet')
121
+
122
+
123
+ def test_Integer():
124
+ sT(Integer(4), "Integer(4)")
125
+
126
+
127
+ def test_list():
128
+ sT([x, Integer(4)], "[Symbol('x'), Integer(4)]")
129
+
130
+
131
+ def test_Matrix():
132
+ for cls, name in [(Matrix, "MutableDenseMatrix"), (ImmutableDenseMatrix, "ImmutableDenseMatrix")]:
133
+ sT(cls([[x**+1, 1], [y, x + y]]),
134
+ "%s([[Symbol('x'), Integer(1)], [Symbol('y'), Add(Symbol('x'), Symbol('y'))]])" % name)
135
+
136
+ sT(cls(), "%s([])" % name)
137
+
138
+ sT(cls([[x**+1, 1], [y, x + y]]), "%s([[Symbol('x'), Integer(1)], [Symbol('y'), Add(Symbol('x'), Symbol('y'))]])" % name)
139
+
140
+
141
+ def test_empty_Matrix():
142
+ sT(ones(0, 3), "MutableDenseMatrix(0, 3, [])")
143
+ sT(ones(4, 0), "MutableDenseMatrix(4, 0, [])")
144
+ sT(ones(0, 0), "MutableDenseMatrix([])")
145
+
146
+
147
+ def test_Rational():
148
+ sT(Rational(1, 3), "Rational(1, 3)")
149
+ sT(Rational(-1, 3), "Rational(-1, 3)")
150
+
151
+
152
+ def test_Float():
153
+ sT(Float('1.23', dps=3), "Float('1.22998', precision=13)")
154
+ sT(Float('1.23456789', dps=9), "Float('1.23456788994', precision=33)")
155
+ sT(Float('1.234567890123456789', dps=19),
156
+ "Float('1.234567890123456789013', precision=66)")
157
+ sT(Float('0.60038617995049726', dps=15),
158
+ "Float('0.60038617995049726', precision=53)")
159
+
160
+ sT(Float('1.23', precision=13), "Float('1.22998', precision=13)")
161
+ sT(Float('1.23456789', precision=33),
162
+ "Float('1.23456788994', precision=33)")
163
+ sT(Float('1.234567890123456789', precision=66),
164
+ "Float('1.234567890123456789013', precision=66)")
165
+ sT(Float('0.60038617995049726', precision=53),
166
+ "Float('0.60038617995049726', precision=53)")
167
+
168
+ sT(Float('0.60038617995049726', 15),
169
+ "Float('0.60038617995049726', precision=53)")
170
+
171
+
172
+ def test_Symbol():
173
+ sT(x, "Symbol('x')")
174
+ sT(y, "Symbol('y')")
175
+ sT(Symbol('x', negative=True), "Symbol('x', negative=True)")
176
+
177
+
178
+ def test_Symbol_two_assumptions():
179
+ x = Symbol('x', negative=0, integer=1)
180
+ # order could vary
181
+ s1 = "Symbol('x', integer=True, negative=False)"
182
+ s2 = "Symbol('x', negative=False, integer=True)"
183
+ assert srepr(x) in (s1, s2)
184
+ assert eval(srepr(x), ENV) == x
185
+
186
+
187
+ def test_Symbol_no_special_commutative_treatment():
188
+ sT(Symbol('x'), "Symbol('x')")
189
+ sT(Symbol('x', commutative=False), "Symbol('x', commutative=False)")
190
+ sT(Symbol('x', commutative=0), "Symbol('x', commutative=False)")
191
+ sT(Symbol('x', commutative=True), "Symbol('x', commutative=True)")
192
+ sT(Symbol('x', commutative=1), "Symbol('x', commutative=True)")
193
+
194
+
195
+ def test_Wild():
196
+ sT(Wild('x', even=True), "Wild('x', even=True)")
197
+
198
+
199
+ def test_Dummy():
200
+ d = Dummy('d')
201
+ sT(d, "Dummy('d', dummy_index=%s)" % str(d.dummy_index))
202
+
203
+
204
+ def test_Dummy_assumption():
205
+ d = Dummy('d', nonzero=True)
206
+ assert d == eval(srepr(d))
207
+ s1 = "Dummy('d', dummy_index=%s, nonzero=True)" % str(d.dummy_index)
208
+ s2 = "Dummy('d', nonzero=True, dummy_index=%s)" % str(d.dummy_index)
209
+ assert srepr(d) in (s1, s2)
210
+
211
+
212
+ def test_Dummy_from_Symbol():
213
+ # should not get the full dictionary of assumptions
214
+ n = Symbol('n', integer=True)
215
+ d = n.as_dummy()
216
+ assert srepr(d
217
+ ) == "Dummy('n', dummy_index=%s)" % str(d.dummy_index)
218
+
219
+
220
+ def test_tuple():
221
+ sT((x,), "(Symbol('x'),)")
222
+ sT((x, y), "(Symbol('x'), Symbol('y'))")
223
+
224
+
225
+ def test_WildFunction():
226
+ sT(WildFunction('w'), "WildFunction('w')")
227
+
228
+
229
+ def test_settins():
230
+ raises(TypeError, lambda: srepr(x, method="garbage"))
231
+
232
+
233
+ def test_Mul():
234
+ sT(3*x**3*y, "Mul(Integer(3), Pow(Symbol('x'), Integer(3)), Symbol('y'))")
235
+ assert srepr(3*x**3*y, order='old') == "Mul(Integer(3), Symbol('y'), Pow(Symbol('x'), Integer(3)))"
236
+ assert srepr(sympify('(x+4)*2*x*7', evaluate=False), order='none') == "Mul(Add(Symbol('x'), Integer(4)), Integer(2), Symbol('x'), Integer(7))"
237
+
238
+
239
+ def test_AlgebraicNumber():
240
+ a = AlgebraicNumber(sqrt(2))
241
+ sT(a, "AlgebraicNumber(Pow(Integer(2), Rational(1, 2)), [Integer(1), Integer(0)])")
242
+ a = AlgebraicNumber(root(-2, 3))
243
+ sT(a, "AlgebraicNumber(Pow(Integer(-2), Rational(1, 3)), [Integer(1), Integer(0)])")
244
+
245
+
246
+ def test_PolyRing():
247
+ assert srepr(ring("x", ZZ, lex)[0]) == "PolyRing((Symbol('x'),), ZZ, lex)"
248
+ assert srepr(ring("x,y", QQ, grlex)[0]) == "PolyRing((Symbol('x'), Symbol('y')), QQ, grlex)"
249
+ assert srepr(ring("x,y,z", ZZ["t"], lex)[0]) == "PolyRing((Symbol('x'), Symbol('y'), Symbol('z')), ZZ[t], lex)"
250
+
251
+
252
+ def test_FracField():
253
+ assert srepr(field("x", ZZ, lex)[0]) == "FracField((Symbol('x'),), ZZ, lex)"
254
+ assert srepr(field("x,y", QQ, grlex)[0]) == "FracField((Symbol('x'), Symbol('y')), QQ, grlex)"
255
+ assert srepr(field("x,y,z", ZZ["t"], lex)[0]) == "FracField((Symbol('x'), Symbol('y'), Symbol('z')), ZZ[t], lex)"
256
+
257
+
258
+ def test_PolyElement():
259
+ R, x, y = ring("x,y", ZZ)
260
+ assert srepr(3*x**2*y + 1) == "PolyElement(PolyRing((Symbol('x'), Symbol('y')), ZZ, lex), [((2, 1), 3), ((0, 0), 1)])"
261
+
262
+
263
+ def test_FracElement():
264
+ F, x, y = field("x,y", ZZ)
265
+ assert srepr((3*x**2*y + 1)/(x - y**2)) == "FracElement(FracField((Symbol('x'), Symbol('y')), ZZ, lex), [((2, 1), 3), ((0, 0), 1)], [((1, 0), 1), ((0, 2), -1)])"
266
+
267
+
268
+ def test_FractionField():
269
+ assert srepr(QQ.frac_field(x)) == \
270
+ "FractionField(FracField((Symbol('x'),), QQ, lex))"
271
+ assert srepr(QQ.frac_field(x, y, order=grlex)) == \
272
+ "FractionField(FracField((Symbol('x'), Symbol('y')), QQ, grlex))"
273
+
274
+
275
+ def test_PolynomialRingBase():
276
+ assert srepr(ZZ.old_poly_ring(x)) == \
277
+ "GlobalPolynomialRing(ZZ, Symbol('x'))"
278
+ assert srepr(ZZ[x].old_poly_ring(y)) == \
279
+ "GlobalPolynomialRing(ZZ[x], Symbol('y'))"
280
+ assert srepr(QQ.frac_field(x).old_poly_ring(y)) == \
281
+ "GlobalPolynomialRing(FractionField(FracField((Symbol('x'),), QQ, lex)), Symbol('y'))"
282
+
283
+
284
+ def test_DMP():
285
+ p1 = DMP([1, 2], ZZ)
286
+ p2 = ZZ.old_poly_ring(x)([1, 2])
287
+ if GROUND_TYPES != 'flint':
288
+ assert srepr(p1) == "DMP_Python([1, 2], ZZ)"
289
+ assert srepr(p2) == "DMP_Python([1, 2], ZZ)"
290
+ else:
291
+ assert srepr(p1) == "DUP_Flint([1, 2], ZZ)"
292
+ assert srepr(p2) == "DUP_Flint([1, 2], ZZ)"
293
+
294
+
295
+ def test_FiniteExtension():
296
+ assert srepr(FiniteExtension(Poly(x**2 + 1, x))) == \
297
+ "FiniteExtension(Poly(x**2 + 1, x, domain='ZZ'))"
298
+
299
+
300
+ def test_ExtensionElement():
301
+ A = FiniteExtension(Poly(x**2 + 1, x))
302
+ if GROUND_TYPES != 'flint':
303
+ ans = "ExtElem(DMP_Python([1, 0], ZZ), FiniteExtension(Poly(x**2 + 1, x, domain='ZZ')))"
304
+ else:
305
+ ans = "ExtElem(DUP_Flint([1, 0], ZZ), FiniteExtension(Poly(x**2 + 1, x, domain='ZZ')))"
306
+ assert srepr(A.generator) == ans
307
+
308
+ def test_BooleanAtom():
309
+ assert srepr(true) == "true"
310
+ assert srepr(false) == "false"
311
+
312
+
313
+ def test_Integers():
314
+ sT(S.Integers, "Integers")
315
+
316
+
317
+ def test_Naturals():
318
+ sT(S.Naturals, "Naturals")
319
+
320
+
321
+ def test_Naturals0():
322
+ sT(S.Naturals0, "Naturals0")
323
+
324
+
325
+ def test_Reals():
326
+ sT(S.Reals, "Reals")
327
+
328
+
329
+ def test_matrix_expressions():
330
+ n = symbols('n', integer=True)
331
+ A = MatrixSymbol("A", n, n)
332
+ B = MatrixSymbol("B", n, n)
333
+ sT(A, "MatrixSymbol(Str('A'), Symbol('n', integer=True), Symbol('n', integer=True))")
334
+ sT(A*B, "MatMul(MatrixSymbol(Str('A'), Symbol('n', integer=True), Symbol('n', integer=True)), MatrixSymbol(Str('B'), Symbol('n', integer=True), Symbol('n', integer=True)))")
335
+ sT(A + B, "MatAdd(MatrixSymbol(Str('A'), Symbol('n', integer=True), Symbol('n', integer=True)), MatrixSymbol(Str('B'), Symbol('n', integer=True), Symbol('n', integer=True)))")
336
+
337
+
338
+ def test_Cycle():
339
+ # FIXME: sT fails because Cycle is not immutable and calling srepr(Cycle(1, 2))
340
+ # adds keys to the Cycle dict (GH-17661)
341
+ #import_stmt = "from sympy.combinatorics import Cycle"
342
+ #sT(Cycle(1, 2), "Cycle(1, 2)", import_stmt)
343
+ assert srepr(Cycle(1, 2)) == "Cycle(1, 2)"
344
+
345
+
346
+ def test_Permutation():
347
+ import_stmt = "from sympy.combinatorics import Permutation"
348
+ sT(Permutation(1, 2)(3, 4), "Permutation([0, 2, 1, 4, 3])", import_stmt, perm_cyclic=False)
349
+ sT(Permutation(1, 2)(3, 4), "Permutation(1, 2)(3, 4)", import_stmt, perm_cyclic=True)
350
+
351
+ with warns_deprecated_sympy():
352
+ old_print_cyclic = Permutation.print_cyclic
353
+ Permutation.print_cyclic = False
354
+ sT(Permutation(1, 2)(3, 4), "Permutation([0, 2, 1, 4, 3])", import_stmt)
355
+ Permutation.print_cyclic = old_print_cyclic
356
+
357
+ def test_dict():
358
+ from sympy.abc import x, y, z
359
+ d = {}
360
+ assert srepr(d) == "{}"
361
+ d = {x: y}
362
+ assert srepr(d) == "{Symbol('x'): Symbol('y')}"
363
+ d = {x: y, y: z}
364
+ assert srepr(d) in (
365
+ "{Symbol('x'): Symbol('y'), Symbol('y'): Symbol('z')}",
366
+ "{Symbol('y'): Symbol('z'), Symbol('x'): Symbol('y')}",
367
+ )
368
+ d = {x: {y: z}}
369
+ assert srepr(d) == "{Symbol('x'): {Symbol('y'): Symbol('z')}}"
370
+
371
+ def test_set():
372
+ from sympy.abc import x, y
373
+ s = set()
374
+ assert srepr(s) == "set()"
375
+ s = {x, y}
376
+ assert srepr(s) in ("{Symbol('x'), Symbol('y')}", "{Symbol('y'), Symbol('x')}")
377
+
378
+ def test_Predicate():
379
+ sT(Q.even, "Q.even")
380
+
381
+ def test_AppliedPredicate():
382
+ sT(Q.even(Symbol('z')), "AppliedPredicate(Q.even, Symbol('z'))")
lib/python3.12/site-packages/sympy/printing/tests/test_smtlib.py ADDED
@@ -0,0 +1,553 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import contextlib
2
+ import itertools
3
+ import re
4
+ import typing
5
+ from enum import Enum
6
+ from typing import Callable
7
+
8
+ import sympy
9
+ from sympy import Add, Implies, sqrt
10
+ from sympy.core import Mul, Pow
11
+ from sympy.core import (S, pi, symbols, Function, Rational, Integer,
12
+ Symbol, Eq, Ne, Le, Lt, Gt, Ge)
13
+ from sympy.functions import Piecewise, exp, sin, cos
14
+ from sympy.assumptions.ask import Q
15
+ from sympy.printing.smtlib import smtlib_code
16
+ from sympy.testing.pytest import raises, Failed
17
+
18
+ x, y, z = symbols('x,y,z')
19
+
20
+
21
+ class _W(Enum):
22
+ DEFAULTING_TO_FLOAT = re.compile("Could not infer type of `.+`. Defaulting to float.", re.I)
23
+ WILL_NOT_DECLARE = re.compile("Non-Symbol/Function `.+` will not be declared.", re.I)
24
+ WILL_NOT_ASSERT = re.compile("Non-Boolean expression `.+` will not be asserted. Converting to SMTLib verbatim.", re.I)
25
+
26
+
27
+ @contextlib.contextmanager
28
+ def _check_warns(expected: typing.Iterable[_W]):
29
+ warns: typing.List[str] = []
30
+ log_warn = warns.append
31
+ yield log_warn
32
+
33
+ errors = []
34
+ for i, (w, e) in enumerate(itertools.zip_longest(warns, expected)):
35
+ if not e:
36
+ errors += [f"[{i}] Received unexpected warning `{w}`."]
37
+ elif not w:
38
+ errors += [f"[{i}] Did not receive expected warning `{e.name}`."]
39
+ elif not e.value.match(w):
40
+ errors += [f"[{i}] Warning `{w}` does not match expected {e.name}."]
41
+
42
+ if errors: raise Failed('\n'.join(errors))
43
+
44
+
45
+ def test_Integer():
46
+ with _check_warns([_W.WILL_NOT_ASSERT] * 2) as w:
47
+ assert smtlib_code(Integer(67), log_warn=w) == "67"
48
+ assert smtlib_code(Integer(-1), log_warn=w) == "-1"
49
+ with _check_warns([]) as w:
50
+ assert smtlib_code(Integer(67)) == "67"
51
+ assert smtlib_code(Integer(-1)) == "-1"
52
+
53
+
54
+ def test_Rational():
55
+ with _check_warns([_W.WILL_NOT_ASSERT] * 4) as w:
56
+ assert smtlib_code(Rational(3, 7), log_warn=w) == "(/ 3 7)"
57
+ assert smtlib_code(Rational(18, 9), log_warn=w) == "2"
58
+ assert smtlib_code(Rational(3, -7), log_warn=w) == "(/ -3 7)"
59
+ assert smtlib_code(Rational(-3, -7), log_warn=w) == "(/ 3 7)"
60
+
61
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT] * 2) as w:
62
+ assert smtlib_code(x + Rational(3, 7), auto_declare=False, log_warn=w) == "(+ (/ 3 7) x)"
63
+ assert smtlib_code(Rational(3, 7) * x, log_warn=w) == "(declare-const x Real)\n" \
64
+ "(* (/ 3 7) x)"
65
+
66
+
67
+ def test_Relational():
68
+ with _check_warns([_W.DEFAULTING_TO_FLOAT] * 12) as w:
69
+ assert smtlib_code(Eq(x, y), auto_declare=False, log_warn=w) == "(assert (= x y))"
70
+ assert smtlib_code(Ne(x, y), auto_declare=False, log_warn=w) == "(assert (not (= x y)))"
71
+ assert smtlib_code(Le(x, y), auto_declare=False, log_warn=w) == "(assert (<= x y))"
72
+ assert smtlib_code(Lt(x, y), auto_declare=False, log_warn=w) == "(assert (< x y))"
73
+ assert smtlib_code(Gt(x, y), auto_declare=False, log_warn=w) == "(assert (> x y))"
74
+ assert smtlib_code(Ge(x, y), auto_declare=False, log_warn=w) == "(assert (>= x y))"
75
+
76
+
77
+ def test_AppliedBinaryRelation():
78
+ with _check_warns([_W.DEFAULTING_TO_FLOAT] * 12) as w:
79
+ assert smtlib_code(Q.eq(x, y), auto_declare=False, log_warn=w) == "(assert (= x y))"
80
+ assert smtlib_code(Q.ne(x, y), auto_declare=False, log_warn=w) == "(assert (not (= x y)))"
81
+ assert smtlib_code(Q.lt(x, y), auto_declare=False, log_warn=w) == "(assert (< x y))"
82
+ assert smtlib_code(Q.le(x, y), auto_declare=False, log_warn=w) == "(assert (<= x y))"
83
+ assert smtlib_code(Q.gt(x, y), auto_declare=False, log_warn=w) == "(assert (> x y))"
84
+ assert smtlib_code(Q.ge(x, y), auto_declare=False, log_warn=w) == "(assert (>= x y))"
85
+
86
+ raises(ValueError, lambda: smtlib_code(Q.complex(x), log_warn=w))
87
+
88
+
89
+ def test_AppliedPredicate():
90
+ with _check_warns([_W.DEFAULTING_TO_FLOAT] * 6) as w:
91
+ assert smtlib_code(Q.positive(x), auto_declare=False, log_warn=w) == "(assert (> x 0))"
92
+ assert smtlib_code(Q.negative(x), auto_declare=False, log_warn=w) == "(assert (< x 0))"
93
+ assert smtlib_code(Q.zero(x), auto_declare=False, log_warn=w) == "(assert (= x 0))"
94
+ assert smtlib_code(Q.nonpositive(x), auto_declare=False, log_warn=w) == "(assert (<= x 0))"
95
+ assert smtlib_code(Q.nonnegative(x), auto_declare=False, log_warn=w) == "(assert (>= x 0))"
96
+ assert smtlib_code(Q.nonzero(x), auto_declare=False, log_warn=w) == "(assert (not (= x 0)))"
97
+
98
+ def test_Function():
99
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
100
+ assert smtlib_code(sin(x) ** cos(x), auto_declare=False, log_warn=w) == "(pow (sin x) (cos x))"
101
+
102
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
103
+ assert smtlib_code(
104
+ abs(x),
105
+ symbol_table={x: int, y: bool},
106
+ known_types={int: "INTEGER_TYPE"},
107
+ known_functions={sympy.Abs: "ABSOLUTE_VALUE_OF"},
108
+ log_warn=w
109
+ ) == "(declare-const x INTEGER_TYPE)\n" \
110
+ "(ABSOLUTE_VALUE_OF x)"
111
+
112
+ my_fun1 = Function('f1')
113
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
114
+ assert smtlib_code(
115
+ my_fun1(x),
116
+ symbol_table={my_fun1: Callable[[bool], float]},
117
+ log_warn=w
118
+ ) == "(declare-const x Bool)\n" \
119
+ "(declare-fun f1 (Bool) Real)\n" \
120
+ "(f1 x)"
121
+
122
+ with _check_warns([]) as w:
123
+ assert smtlib_code(
124
+ my_fun1(x),
125
+ symbol_table={my_fun1: Callable[[bool], bool]},
126
+ log_warn=w
127
+ ) == "(declare-const x Bool)\n" \
128
+ "(declare-fun f1 (Bool) Bool)\n" \
129
+ "(assert (f1 x))"
130
+
131
+ assert smtlib_code(
132
+ Eq(my_fun1(x, z), y),
133
+ symbol_table={my_fun1: Callable[[int, bool], bool]},
134
+ log_warn=w
135
+ ) == "(declare-const x Int)\n" \
136
+ "(declare-const y Bool)\n" \
137
+ "(declare-const z Bool)\n" \
138
+ "(declare-fun f1 (Int Bool) Bool)\n" \
139
+ "(assert (= (f1 x z) y))"
140
+
141
+ assert smtlib_code(
142
+ Eq(my_fun1(x, z), y),
143
+ symbol_table={my_fun1: Callable[[int, bool], bool]},
144
+ known_functions={my_fun1: "MY_KNOWN_FUN", Eq: '=='},
145
+ log_warn=w
146
+ ) == "(declare-const x Int)\n" \
147
+ "(declare-const y Bool)\n" \
148
+ "(declare-const z Bool)\n" \
149
+ "(assert (== (MY_KNOWN_FUN x z) y))"
150
+
151
+ with _check_warns([_W.DEFAULTING_TO_FLOAT] * 3) as w:
152
+ assert smtlib_code(
153
+ Eq(my_fun1(x, z), y),
154
+ known_functions={my_fun1: "MY_KNOWN_FUN", Eq: '=='},
155
+ log_warn=w
156
+ ) == "(declare-const x Real)\n" \
157
+ "(declare-const y Real)\n" \
158
+ "(declare-const z Real)\n" \
159
+ "(assert (== (MY_KNOWN_FUN x z) y))"
160
+
161
+
162
+ def test_Pow():
163
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
164
+ assert smtlib_code(x ** 3, auto_declare=False, log_warn=w) == "(pow x 3)"
165
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
166
+ assert smtlib_code(x ** (y ** 3), auto_declare=False, log_warn=w) == "(pow x (pow y 3))"
167
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
168
+ assert smtlib_code(x ** Rational(2, 3), auto_declare=False, log_warn=w) == '(pow x (/ 2 3))'
169
+
170
+ a = Symbol('a', integer=True)
171
+ b = Symbol('b', real=True)
172
+ c = Symbol('c')
173
+
174
+ def g(x): return 2 * x
175
+
176
+ # if x=1, y=2, then expr=2.333...
177
+ expr = 1 / (g(a) * 3.5) ** (a - b ** a) / (a ** 2 + b)
178
+
179
+ with _check_warns([]) as w:
180
+ assert smtlib_code(
181
+ [
182
+ Eq(a < 2, c),
183
+ Eq(b > a, c),
184
+ c & True,
185
+ Eq(expr, 2 + Rational(1, 3))
186
+ ],
187
+ log_warn=w
188
+ ) == '(declare-const a Int)\n' \
189
+ '(declare-const b Real)\n' \
190
+ '(declare-const c Bool)\n' \
191
+ '(assert (= (< a 2) c))\n' \
192
+ '(assert (= (> b a) c))\n' \
193
+ '(assert c)\n' \
194
+ '(assert (= ' \
195
+ '(* (pow (* 7.0 a) (+ (pow b a) (* -1 a))) (pow (+ b (pow a 2)) -1)) ' \
196
+ '(/ 7 3)' \
197
+ '))'
198
+
199
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
200
+ assert smtlib_code(
201
+ Mul(-2, c, Pow(Mul(b, b, evaluate=False), -1, evaluate=False), evaluate=False),
202
+ log_warn=w
203
+ ) == '(declare-const b Real)\n' \
204
+ '(declare-const c Real)\n' \
205
+ '(* -2 c (pow (* b b) -1))'
206
+
207
+
208
+ def test_basic_ops():
209
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
210
+ assert smtlib_code(x * y, auto_declare=False, log_warn=w) == "(* x y)"
211
+
212
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
213
+ assert smtlib_code(x + y, auto_declare=False, log_warn=w) == "(+ x y)"
214
+
215
+ # with _check_warns([_SmtlibWarnings.DEFAULTING_TO_FLOAT, _SmtlibWarnings.DEFAULTING_TO_FLOAT, _SmtlibWarnings.WILL_NOT_ASSERT]) as w:
216
+ # todo: implement re-write, currently does '(+ x (* -1 y))' instead
217
+ # assert smtlib_code(x - y, auto_declare=False, log_warn=w) == "(- x y)"
218
+
219
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
220
+ assert smtlib_code(-x, auto_declare=False, log_warn=w) == "(* -1 x)"
221
+
222
+
223
+ def test_quantifier_extensions():
224
+ from sympy.logic.boolalg import Boolean
225
+ from sympy import Interval, Tuple, sympify
226
+
227
+ # start For-all quantifier class example
228
+ class ForAll(Boolean):
229
+ def _smtlib(self, printer):
230
+ bound_symbol_declarations = [
231
+ printer._s_expr(sym.name, [
232
+ printer._known_types[printer.symbol_table[sym]],
233
+ Interval(start, end)
234
+ ]) for sym, start, end in self.limits
235
+ ]
236
+ return printer._s_expr('forall', [
237
+ printer._s_expr('', bound_symbol_declarations),
238
+ self.function
239
+ ])
240
+
241
+ @property
242
+ def bound_symbols(self):
243
+ return {s for s, _, _ in self.limits}
244
+
245
+ @property
246
+ def free_symbols(self):
247
+ bound_symbol_names = {s.name for s in self.bound_symbols}
248
+ return {
249
+ s for s in self.function.free_symbols
250
+ if s.name not in bound_symbol_names
251
+ }
252
+
253
+ def __new__(cls, *args):
254
+ limits = [sympify(a) for a in args if isinstance(a, (tuple, Tuple))]
255
+ function = [sympify(a) for a in args if isinstance(a, Boolean)]
256
+ assert len(limits) + len(function) == len(args)
257
+ assert len(function) == 1
258
+ function = function[0]
259
+
260
+ if isinstance(function, ForAll): return ForAll.__new__(
261
+ ForAll, *(limits + function.limits), function.function
262
+ )
263
+ inst = Boolean.__new__(cls)
264
+ inst._args = tuple(limits + [function])
265
+ inst.limits = limits
266
+ inst.function = function
267
+ return inst
268
+
269
+ # end For-All Quantifier class example
270
+
271
+ f = Function('f')
272
+ with _check_warns([_W.DEFAULTING_TO_FLOAT]) as w:
273
+ assert smtlib_code(
274
+ ForAll((x, -42, +21), Eq(f(x), f(x))),
275
+ symbol_table={f: Callable[[float], float]},
276
+ log_warn=w
277
+ ) == '(assert (forall ( (x Real [-42, 21])) true))'
278
+
279
+ with _check_warns([_W.DEFAULTING_TO_FLOAT] * 2) as w:
280
+ assert smtlib_code(
281
+ ForAll(
282
+ (x, -42, +21), (y, -100, 3),
283
+ Implies(Eq(x, y), Eq(f(x), f(y)))
284
+ ),
285
+ symbol_table={f: Callable[[float], float]},
286
+ log_warn=w
287
+ ) == '(declare-fun f (Real) Real)\n' \
288
+ '(assert (' \
289
+ 'forall ( (x Real [-42, 21]) (y Real [-100, 3])) ' \
290
+ '(=> (= x y) (= (f x) (f y)))' \
291
+ '))'
292
+
293
+ a = Symbol('a', integer=True)
294
+ b = Symbol('b', real=True)
295
+ c = Symbol('c')
296
+
297
+ with _check_warns([]) as w:
298
+ assert smtlib_code(
299
+ ForAll(
300
+ (a, 2, 100), ForAll(
301
+ (b, 2, 100),
302
+ Implies(a < b, sqrt(a) < b) | c
303
+ )),
304
+ log_warn=w
305
+ ) == '(declare-const c Bool)\n' \
306
+ '(assert (forall ( (a Int [2, 100]) (b Real [2, 100])) ' \
307
+ '(or c (=> (< a b) (< (pow a (/ 1 2)) b)))' \
308
+ '))'
309
+
310
+
311
+ def test_mix_number_mult_symbols():
312
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
313
+ assert smtlib_code(
314
+ 1 / pi,
315
+ known_constants={pi: "MY_PI"},
316
+ log_warn=w
317
+ ) == '(pow MY_PI -1)'
318
+
319
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
320
+ assert smtlib_code(
321
+ [
322
+ Eq(pi, 3.14, evaluate=False),
323
+ 1 / pi,
324
+ ],
325
+ known_constants={pi: "MY_PI"},
326
+ log_warn=w
327
+ ) == '(assert (= MY_PI 3.14))\n' \
328
+ '(pow MY_PI -1)'
329
+
330
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
331
+ assert smtlib_code(
332
+ Add(S.Zero, S.One, S.NegativeOne, S.Half,
333
+ S.Exp1, S.Pi, S.GoldenRatio, evaluate=False),
334
+ known_constants={
335
+ S.Pi: 'p', S.GoldenRatio: 'g',
336
+ S.Exp1: 'e'
337
+ },
338
+ known_functions={
339
+ Add: 'plus',
340
+ exp: 'exp'
341
+ },
342
+ precision=3,
343
+ log_warn=w
344
+ ) == '(plus 0 1 -1 (/ 1 2) (exp 1) p g)'
345
+
346
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
347
+ assert smtlib_code(
348
+ Add(S.Zero, S.One, S.NegativeOne, S.Half,
349
+ S.Exp1, S.Pi, S.GoldenRatio, evaluate=False),
350
+ known_constants={
351
+ S.Pi: 'p'
352
+ },
353
+ known_functions={
354
+ Add: 'plus',
355
+ exp: 'exp'
356
+ },
357
+ precision=3,
358
+ log_warn=w
359
+ ) == '(plus 0 1 -1 (/ 1 2) (exp 1) p 1.62)'
360
+
361
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
362
+ assert smtlib_code(
363
+ Add(S.Zero, S.One, S.NegativeOne, S.Half,
364
+ S.Exp1, S.Pi, S.GoldenRatio, evaluate=False),
365
+ known_functions={Add: 'plus'},
366
+ precision=3,
367
+ log_warn=w
368
+ ) == '(plus 0 1 -1 (/ 1 2) 2.72 3.14 1.62)'
369
+
370
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
371
+ assert smtlib_code(
372
+ Add(S.Zero, S.One, S.NegativeOne, S.Half,
373
+ S.Exp1, S.Pi, S.GoldenRatio, evaluate=False),
374
+ known_constants={S.Exp1: 'e'},
375
+ known_functions={Add: 'plus'},
376
+ precision=3,
377
+ log_warn=w
378
+ ) == '(plus 0 1 -1 (/ 1 2) e 3.14 1.62)'
379
+
380
+
381
+ def test_boolean():
382
+ with _check_warns([]) as w:
383
+ assert smtlib_code(x & y, log_warn=w) == '(declare-const x Bool)\n' \
384
+ '(declare-const y Bool)\n' \
385
+ '(assert (and x y))'
386
+ assert smtlib_code(x | y, log_warn=w) == '(declare-const x Bool)\n' \
387
+ '(declare-const y Bool)\n' \
388
+ '(assert (or x y))'
389
+ assert smtlib_code(~x, log_warn=w) == '(declare-const x Bool)\n' \
390
+ '(assert (not x))'
391
+ assert smtlib_code(x & y & z, log_warn=w) == '(declare-const x Bool)\n' \
392
+ '(declare-const y Bool)\n' \
393
+ '(declare-const z Bool)\n' \
394
+ '(assert (and x y z))'
395
+
396
+ with _check_warns([_W.DEFAULTING_TO_FLOAT]) as w:
397
+ assert smtlib_code((x & ~y) | (z > 3), log_warn=w) == '(declare-const x Bool)\n' \
398
+ '(declare-const y Bool)\n' \
399
+ '(declare-const z Real)\n' \
400
+ '(assert (or (> z 3) (and x (not y))))'
401
+
402
+ f = Function('f')
403
+ g = Function('g')
404
+ h = Function('h')
405
+ with _check_warns([_W.DEFAULTING_TO_FLOAT]) as w:
406
+ assert smtlib_code(
407
+ [Gt(f(x), y),
408
+ Lt(y, g(z))],
409
+ symbol_table={
410
+ f: Callable[[bool], int], g: Callable[[bool], int],
411
+ }, log_warn=w
412
+ ) == '(declare-const x Bool)\n' \
413
+ '(declare-const y Real)\n' \
414
+ '(declare-const z Bool)\n' \
415
+ '(declare-fun f (Bool) Int)\n' \
416
+ '(declare-fun g (Bool) Int)\n' \
417
+ '(assert (> (f x) y))\n' \
418
+ '(assert (< y (g z)))'
419
+
420
+ with _check_warns([]) as w:
421
+ assert smtlib_code(
422
+ [Eq(f(x), y),
423
+ Lt(y, g(z))],
424
+ symbol_table={
425
+ f: Callable[[bool], int], g: Callable[[bool], int],
426
+ }, log_warn=w
427
+ ) == '(declare-const x Bool)\n' \
428
+ '(declare-const y Int)\n' \
429
+ '(declare-const z Bool)\n' \
430
+ '(declare-fun f (Bool) Int)\n' \
431
+ '(declare-fun g (Bool) Int)\n' \
432
+ '(assert (= (f x) y))\n' \
433
+ '(assert (< y (g z)))'
434
+
435
+ with _check_warns([]) as w:
436
+ assert smtlib_code(
437
+ [Eq(f(x), y),
438
+ Eq(g(f(x)), z),
439
+ Eq(h(g(f(x))), x)],
440
+ symbol_table={
441
+ f: Callable[[float], int],
442
+ g: Callable[[int], bool],
443
+ h: Callable[[bool], float]
444
+ },
445
+ log_warn=w
446
+ ) == '(declare-const x Real)\n' \
447
+ '(declare-const y Int)\n' \
448
+ '(declare-const z Bool)\n' \
449
+ '(declare-fun f (Real) Int)\n' \
450
+ '(declare-fun g (Int) Bool)\n' \
451
+ '(declare-fun h (Bool) Real)\n' \
452
+ '(assert (= (f x) y))\n' \
453
+ '(assert (= (g (f x)) z))\n' \
454
+ '(assert (= (h (g (f x))) x))'
455
+
456
+
457
+ # todo: make smtlib_code support arrays
458
+ # def test_containers():
459
+ # assert julia_code([1, 2, 3, [4, 5, [6, 7]], 8, [9, 10], 11]) == \
460
+ # "Any[1, 2, 3, Any[4, 5, Any[6, 7]], 8, Any[9, 10], 11]"
461
+ # assert julia_code((1, 2, (3, 4))) == "(1, 2, (3, 4))"
462
+ # assert julia_code([1]) == "Any[1]"
463
+ # assert julia_code((1,)) == "(1,)"
464
+ # assert julia_code(Tuple(*[1, 2, 3])) == "(1, 2, 3)"
465
+ # assert julia_code((1, x * y, (3, x ** 2))) == "(1, x .* y, (3, x .^ 2))"
466
+ # # scalar, matrix, empty matrix and empty list
467
+ # assert julia_code((1, eye(3), Matrix(0, 0, []), [])) == "(1, [1 0 0;\n0 1 0;\n0 0 1], zeros(0, 0), Any[])"
468
+
469
+ def test_smtlib_piecewise():
470
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
471
+ assert smtlib_code(
472
+ Piecewise((x, x < 1),
473
+ (x ** 2, True)),
474
+ auto_declare=False,
475
+ log_warn=w
476
+ ) == '(ite (< x 1) x (pow x 2))'
477
+
478
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
479
+ assert smtlib_code(
480
+ Piecewise((x ** 2, x < 1),
481
+ (x ** 3, x < 2),
482
+ (x ** 4, x < 3),
483
+ (x ** 5, True)),
484
+ auto_declare=False,
485
+ log_warn=w
486
+ ) == '(ite (< x 1) (pow x 2) ' \
487
+ '(ite (< x 2) (pow x 3) ' \
488
+ '(ite (< x 3) (pow x 4) ' \
489
+ '(pow x 5))))'
490
+
491
+ # Check that Piecewise without a True (default) condition error
492
+ expr = Piecewise((x, x < 1), (x ** 2, x > 1), (sin(x), x > 0))
493
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
494
+ raises(AssertionError, lambda: smtlib_code(expr, log_warn=w))
495
+
496
+
497
+ def test_smtlib_piecewise_times_const():
498
+ pw = Piecewise((x, x < 1), (x ** 2, True))
499
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
500
+ assert smtlib_code(2 * pw, log_warn=w) == '(declare-const x Real)\n(* 2 (ite (< x 1) x (pow x 2)))'
501
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
502
+ assert smtlib_code(pw / x, log_warn=w) == '(declare-const x Real)\n(* (pow x -1) (ite (< x 1) x (pow x 2)))'
503
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
504
+ assert smtlib_code(pw / (x * y), log_warn=w) == '(declare-const x Real)\n(declare-const y Real)\n(* (pow x -1) (pow y -1) (ite (< x 1) x (pow x 2)))'
505
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
506
+ assert smtlib_code(pw / 3, log_warn=w) == '(declare-const x Real)\n(* (/ 1 3) (ite (< x 1) x (pow x 2)))'
507
+
508
+
509
+ # todo: make smtlib_code support arrays / matrices ?
510
+ # def test_smtlib_matrix_assign_to():
511
+ # A = Matrix([[1, 2, 3]])
512
+ # assert smtlib_code(A, assign_to='a') == "a = [1 2 3]"
513
+ # A = Matrix([[1, 2], [3, 4]])
514
+ # assert smtlib_code(A, assign_to='A') == "A = [1 2;\n3 4]"
515
+
516
+ # def test_julia_matrix_1x1():
517
+ # A = Matrix([[3]])
518
+ # B = MatrixSymbol('B', 1, 1)
519
+ # C = MatrixSymbol('C', 1, 2)
520
+ # assert julia_code(A, assign_to=B) == "B = [3]"
521
+ # raises(ValueError, lambda: julia_code(A, assign_to=C))
522
+
523
+ # def test_julia_matrix_elements():
524
+ # A = Matrix([[x, 2, x * y]])
525
+ # assert julia_code(A[0, 0] ** 2 + A[0, 1] + A[0, 2]) == "x .^ 2 + x .* y + 2"
526
+ # A = MatrixSymbol('AA', 1, 3)
527
+ # assert julia_code(A) == "AA"
528
+ # assert julia_code(A[0, 0] ** 2 + sin(A[0, 1]) + A[0, 2]) == \
529
+ # "sin(AA[1,2]) + AA[1,1] .^ 2 + AA[1,3]"
530
+ # assert julia_code(sum(A)) == "AA[1,1] + AA[1,2] + AA[1,3]"
531
+
532
+ def test_smtlib_boolean():
533
+ with _check_warns([]) as w:
534
+ assert smtlib_code(True, auto_assert=False, log_warn=w) == 'true'
535
+ assert smtlib_code(True, log_warn=w) == '(assert true)'
536
+ assert smtlib_code(S.true, log_warn=w) == '(assert true)'
537
+ assert smtlib_code(S.false, log_warn=w) == '(assert false)'
538
+ assert smtlib_code(False, log_warn=w) == '(assert false)'
539
+ assert smtlib_code(False, auto_assert=False, log_warn=w) == 'false'
540
+
541
+
542
+ def test_not_supported():
543
+ f = Function('f')
544
+ with _check_warns([_W.DEFAULTING_TO_FLOAT, _W.WILL_NOT_ASSERT]) as w:
545
+ raises(KeyError, lambda: smtlib_code(f(x).diff(x), symbol_table={f: Callable[[float], float]}, log_warn=w))
546
+ with _check_warns([_W.WILL_NOT_ASSERT]) as w:
547
+ raises(KeyError, lambda: smtlib_code(S.ComplexInfinity, log_warn=w))
548
+
549
+
550
+ def test_Float():
551
+ assert smtlib_code(0.0) == "0.0"
552
+ assert smtlib_code(0.000000000000000003) == '(* 3.0 (pow 10 -18))'
553
+ assert smtlib_code(5.3) == "5.3"
lib/python3.12/site-packages/sympy/printing/tests/test_str.py ADDED
@@ -0,0 +1,1199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy import MatAdd
2
+ from sympy.algebras.quaternion import Quaternion
3
+ from sympy.assumptions.ask import Q
4
+ from sympy.calculus.accumulationbounds import AccumBounds
5
+ from sympy.combinatorics.partitions import Partition
6
+ from sympy.concrete.summations import (Sum, summation)
7
+ from sympy.core.add import Add
8
+ from sympy.core.containers import (Dict, Tuple)
9
+ from sympy.core.expr import UnevaluatedExpr, Expr
10
+ from sympy.core.function import (Derivative, Function, Lambda, Subs, WildFunction)
11
+ from sympy.core.mul import Mul
12
+ from sympy.core import (Catalan, EulerGamma, GoldenRatio, TribonacciConstant)
13
+ from sympy.core.numbers import (E, Float, I, Integer, Rational, nan, oo, pi, zoo)
14
+ from sympy.core.parameters import _exp_is_pow
15
+ from sympy.core.power import Pow
16
+ from sympy.core.relational import (Eq, Rel, Ne)
17
+ from sympy.core.singleton import S
18
+ from sympy.core.symbol import (Dummy, Symbol, Wild, symbols)
19
+ from sympy.functions.combinatorial.factorials import (factorial, factorial2, subfactorial)
20
+ from sympy.functions.elementary.complexes import Abs
21
+ from sympy.functions.elementary.exponential import exp
22
+ from sympy.functions.elementary.miscellaneous import sqrt
23
+ from sympy.functions.elementary.trigonometric import (cos, sin)
24
+ from sympy.functions.special.delta_functions import Heaviside
25
+ from sympy.functions.special.zeta_functions import zeta
26
+ from sympy.integrals.integrals import Integral
27
+ from sympy.logic.boolalg import (Equivalent, false, true, Xor)
28
+ from sympy.matrices.dense import Matrix
29
+ from sympy.matrices.expressions.matexpr import MatrixSymbol
30
+ from sympy.matrices.expressions import Identity
31
+ from sympy.matrices.expressions.slice import MatrixSlice
32
+ from sympy.matrices import SparseMatrix
33
+ from sympy.polys.polytools import factor
34
+ from sympy.series.limits import Limit
35
+ from sympy.series.order import O
36
+ from sympy.sets.sets import (Complement, FiniteSet, Interval, SymmetricDifference)
37
+ from sympy.stats import (Covariance, Expectation, Probability, Variance)
38
+ from sympy.stats.rv import RandomSymbol
39
+ from sympy.external import import_module
40
+ from sympy.physics.control.lti import TransferFunction, Series, Parallel, \
41
+ Feedback, TransferFunctionMatrix, MIMOSeries, MIMOParallel, MIMOFeedback
42
+ from sympy.physics.units import second, joule
43
+ from sympy.polys import (Poly, rootof, RootSum, groebner, ring, field, ZZ, QQ,
44
+ ZZ_I, QQ_I, lex, grlex)
45
+ from sympy.geometry import Point, Circle, Polygon, Ellipse, Triangle
46
+ from sympy.tensor import NDimArray
47
+ from sympy.tensor.array.expressions.array_expressions import ArraySymbol, ArrayElement
48
+
49
+ from sympy.testing.pytest import raises, warns_deprecated_sympy
50
+
51
+ from sympy.printing import sstr, sstrrepr, StrPrinter
52
+ from sympy.physics.quantum.trace import Tr
53
+
54
+ x, y, z, w, t = symbols('x,y,z,w,t')
55
+ d = Dummy('d')
56
+
57
+
58
+ def test_printmethod():
59
+ class R(Abs):
60
+ def _sympystr(self, printer):
61
+ return "foo(%s)" % printer._print(self.args[0])
62
+ assert sstr(R(x)) == "foo(x)"
63
+
64
+ class R(Abs):
65
+ def _sympystr(self, printer):
66
+ return "foo"
67
+ assert sstr(R(x)) == "foo"
68
+
69
+
70
+ def test_Abs():
71
+ assert str(Abs(x)) == "Abs(x)"
72
+ assert str(Abs(Rational(1, 6))) == "1/6"
73
+ assert str(Abs(Rational(-1, 6))) == "1/6"
74
+
75
+
76
+ def test_Add():
77
+ assert str(x + y) == "x + y"
78
+ assert str(x + 1) == "x + 1"
79
+ assert str(x + x**2) == "x**2 + x"
80
+ assert str(Add(0, 1, evaluate=False)) == "0 + 1"
81
+ assert str(Add(0, 0, 1, evaluate=False)) == "0 + 0 + 1"
82
+ assert str(1.0*x) == "1.0*x"
83
+ assert str(5 + x + y + x*y + x**2 + y**2) == "x**2 + x*y + x + y**2 + y + 5"
84
+ assert str(1 + x + x**2/2 + x**3/3) == "x**3/3 + x**2/2 + x + 1"
85
+ assert str(2*x - 7*x**2 + 2 + 3*y) == "-7*x**2 + 2*x + 3*y + 2"
86
+ assert str(x - y) == "x - y"
87
+ assert str(2 - x) == "2 - x"
88
+ assert str(x - 2) == "x - 2"
89
+ assert str(x - y - z - w) == "-w + x - y - z"
90
+ assert str(x - z*y**2*z*w) == "-w*y**2*z**2 + x"
91
+ assert str(x - 1*y*x*y) == "-x*y**2 + x"
92
+ assert str(sin(x).series(x, 0, 15)) == "x - x**3/6 + x**5/120 - x**7/5040 + x**9/362880 - x**11/39916800 + x**13/6227020800 + O(x**15)"
93
+ assert str(Add(Add(-w, x, evaluate=False), Add(-y, z, evaluate=False), evaluate=False)) == "(-w + x) + (-y + z)"
94
+ assert str(Add(Add(-x, -y, evaluate=False), -z, evaluate=False)) == "-z + (-x - y)"
95
+ assert str(Add(Add(Add(-x, -y, evaluate=False), -z, evaluate=False), -t, evaluate=False)) == "-t + (-z + (-x - y))"
96
+
97
+
98
+ def test_Catalan():
99
+ assert str(Catalan) == "Catalan"
100
+
101
+
102
+ def test_ComplexInfinity():
103
+ assert str(zoo) == "zoo"
104
+
105
+
106
+ def test_Derivative():
107
+ assert str(Derivative(x, y)) == "Derivative(x, y)"
108
+ assert str(Derivative(x**2, x, evaluate=False)) == "Derivative(x**2, x)"
109
+ assert str(Derivative(
110
+ x**2/y, x, y, evaluate=False)) == "Derivative(x**2/y, x, y)"
111
+
112
+
113
+ def test_dict():
114
+ assert str({1: 1 + x}) == sstr({1: 1 + x}) == "{1: x + 1}"
115
+ assert str({1: x**2, 2: y*x}) in ("{1: x**2, 2: x*y}", "{2: x*y, 1: x**2}")
116
+ assert sstr({1: x**2, 2: y*x}) == "{1: x**2, 2: x*y}"
117
+
118
+
119
+ def test_Dict():
120
+ assert str(Dict({1: 1 + x})) == sstr({1: 1 + x}) == "{1: x + 1}"
121
+ assert str(Dict({1: x**2, 2: y*x})) in (
122
+ "{1: x**2, 2: x*y}", "{2: x*y, 1: x**2}")
123
+ assert sstr(Dict({1: x**2, 2: y*x})) == "{1: x**2, 2: x*y}"
124
+
125
+
126
+ def test_Dummy():
127
+ assert str(d) == "_d"
128
+ assert str(d + x) == "_d + x"
129
+
130
+
131
+ def test_EulerGamma():
132
+ assert str(EulerGamma) == "EulerGamma"
133
+
134
+
135
+ def test_Exp():
136
+ assert str(E) == "E"
137
+ with _exp_is_pow(True):
138
+ assert str(exp(x)) == "E**x"
139
+
140
+
141
+ def test_factorial():
142
+ n = Symbol('n', integer=True)
143
+ assert str(factorial(-2)) == "zoo"
144
+ assert str(factorial(0)) == "1"
145
+ assert str(factorial(7)) == "5040"
146
+ assert str(factorial(n)) == "factorial(n)"
147
+ assert str(factorial(2*n)) == "factorial(2*n)"
148
+ assert str(factorial(factorial(n))) == 'factorial(factorial(n))'
149
+ assert str(factorial(factorial2(n))) == 'factorial(factorial2(n))'
150
+ assert str(factorial2(factorial(n))) == 'factorial2(factorial(n))'
151
+ assert str(factorial2(factorial2(n))) == 'factorial2(factorial2(n))'
152
+ assert str(subfactorial(3)) == "2"
153
+ assert str(subfactorial(n)) == "subfactorial(n)"
154
+ assert str(subfactorial(2*n)) == "subfactorial(2*n)"
155
+
156
+
157
+ def test_Function():
158
+ f = Function('f')
159
+ fx = f(x)
160
+ w = WildFunction('w')
161
+ assert str(f) == "f"
162
+ assert str(fx) == "f(x)"
163
+ assert str(w) == "w_"
164
+
165
+
166
+ def test_Geometry():
167
+ assert sstr(Point(0, 0)) == 'Point2D(0, 0)'
168
+ assert sstr(Circle(Point(0, 0), 3)) == 'Circle(Point2D(0, 0), 3)'
169
+ assert sstr(Ellipse(Point(1, 2), 3, 4)) == 'Ellipse(Point2D(1, 2), 3, 4)'
170
+ assert sstr(Triangle(Point(1, 1), Point(7, 8), Point(0, -1))) == \
171
+ 'Triangle(Point2D(1, 1), Point2D(7, 8), Point2D(0, -1))'
172
+ assert sstr(Polygon(Point(5, 6), Point(-2, -3), Point(0, 0), Point(4, 7))) == \
173
+ 'Polygon(Point2D(5, 6), Point2D(-2, -3), Point2D(0, 0), Point2D(4, 7))'
174
+ assert sstr(Triangle(Point(0, 0), Point(1, 0), Point(0, 1)), sympy_integers=True) == \
175
+ 'Triangle(Point2D(S(0), S(0)), Point2D(S(1), S(0)), Point2D(S(0), S(1)))'
176
+ assert sstr(Ellipse(Point(1, 2), 3, 4), sympy_integers=True) == \
177
+ 'Ellipse(Point2D(S(1), S(2)), S(3), S(4))'
178
+
179
+
180
+ def test_GoldenRatio():
181
+ assert str(GoldenRatio) == "GoldenRatio"
182
+
183
+
184
+ def test_Heaviside():
185
+ assert str(Heaviside(x)) == str(Heaviside(x, S.Half)) == "Heaviside(x)"
186
+ assert str(Heaviside(x, 1)) == "Heaviside(x, 1)"
187
+
188
+
189
+ def test_TribonacciConstant():
190
+ assert str(TribonacciConstant) == "TribonacciConstant"
191
+
192
+
193
+ def test_ImaginaryUnit():
194
+ assert str(I) == "I"
195
+
196
+
197
+ def test_Infinity():
198
+ assert str(oo) == "oo"
199
+ assert str(oo*I) == "oo*I"
200
+
201
+
202
+ def test_Integer():
203
+ assert str(Integer(-1)) == "-1"
204
+ assert str(Integer(1)) == "1"
205
+ assert str(Integer(-3)) == "-3"
206
+ assert str(Integer(0)) == "0"
207
+ assert str(Integer(25)) == "25"
208
+
209
+
210
+ def test_Integral():
211
+ assert str(Integral(sin(x), y)) == "Integral(sin(x), y)"
212
+ assert str(Integral(sin(x), (y, 0, 1))) == "Integral(sin(x), (y, 0, 1))"
213
+
214
+
215
+ def test_Interval():
216
+ n = (S.NegativeInfinity, 1, 2, S.Infinity)
217
+ for i in range(len(n)):
218
+ for j in range(i + 1, len(n)):
219
+ for l in (True, False):
220
+ for r in (True, False):
221
+ ival = Interval(n[i], n[j], l, r)
222
+ assert S(str(ival)) == ival
223
+
224
+
225
+ def test_AccumBounds():
226
+ a = Symbol('a', real=True)
227
+ assert str(AccumBounds(0, a)) == "AccumBounds(0, a)"
228
+ assert str(AccumBounds(0, 1)) == "AccumBounds(0, 1)"
229
+
230
+
231
+ def test_Lambda():
232
+ assert str(Lambda(d, d**2)) == "Lambda(_d, _d**2)"
233
+ # issue 2908
234
+ assert str(Lambda((), 1)) == "Lambda((), 1)"
235
+ assert str(Lambda((), x)) == "Lambda((), x)"
236
+ assert str(Lambda((x, y), x+y)) == "Lambda((x, y), x + y)"
237
+ assert str(Lambda(((x, y),), x+y)) == "Lambda(((x, y),), x + y)"
238
+
239
+
240
+ def test_Limit():
241
+ assert str(Limit(sin(x)/x, x, y)) == "Limit(sin(x)/x, x, y, dir='+')"
242
+ assert str(Limit(1/x, x, 0)) == "Limit(1/x, x, 0, dir='+')"
243
+ assert str(
244
+ Limit(sin(x)/x, x, y, dir="-")) == "Limit(sin(x)/x, x, y, dir='-')"
245
+
246
+
247
+ def test_list():
248
+ assert str([x]) == sstr([x]) == "[x]"
249
+ assert str([x**2, x*y + 1]) == sstr([x**2, x*y + 1]) == "[x**2, x*y + 1]"
250
+ assert str([x**2, [y + x]]) == sstr([x**2, [y + x]]) == "[x**2, [x + y]]"
251
+
252
+
253
+ def test_Matrix_str():
254
+ M = Matrix([[x**+1, 1], [y, x + y]])
255
+ assert str(M) == "Matrix([[x, 1], [y, x + y]])"
256
+ assert sstr(M) == "Matrix([\n[x, 1],\n[y, x + y]])"
257
+ M = Matrix([[1]])
258
+ assert str(M) == sstr(M) == "Matrix([[1]])"
259
+ M = Matrix([[1, 2]])
260
+ assert str(M) == sstr(M) == "Matrix([[1, 2]])"
261
+ M = Matrix()
262
+ assert str(M) == sstr(M) == "Matrix(0, 0, [])"
263
+ M = Matrix(0, 1, lambda i, j: 0)
264
+ assert str(M) == sstr(M) == "Matrix(0, 1, [])"
265
+
266
+
267
+ def test_Mul():
268
+ assert str(x/y) == "x/y"
269
+ assert str(y/x) == "y/x"
270
+ assert str(x/y/z) == "x/(y*z)"
271
+ assert str((x + 1)/(y + 2)) == "(x + 1)/(y + 2)"
272
+ assert str(2*x/3) == '2*x/3'
273
+ assert str(-2*x/3) == '-2*x/3'
274
+ assert str(-1.0*x) == '-1.0*x'
275
+ assert str(1.0*x) == '1.0*x'
276
+ assert str(Mul(0, 1, evaluate=False)) == '0*1'
277
+ assert str(Mul(1, 0, evaluate=False)) == '1*0'
278
+ assert str(Mul(1, 1, evaluate=False)) == '1*1'
279
+ assert str(Mul(1, 1, 1, evaluate=False)) == '1*1*1'
280
+ assert str(Mul(1, 2, evaluate=False)) == '1*2'
281
+ assert str(Mul(1, S.Half, evaluate=False)) == '1*(1/2)'
282
+ assert str(Mul(1, 1, S.Half, evaluate=False)) == '1*1*(1/2)'
283
+ assert str(Mul(1, 1, 2, 3, x, evaluate=False)) == '1*1*2*3*x'
284
+ assert str(Mul(1, -1, evaluate=False)) == '1*(-1)'
285
+ assert str(Mul(-1, 1, evaluate=False)) == '-1*1'
286
+ assert str(Mul(4, 3, 2, 1, 0, y, x, evaluate=False)) == '4*3*2*1*0*y*x'
287
+ assert str(Mul(4, 3, 2, 1+z, 0, y, x, evaluate=False)) == '4*3*2*(z + 1)*0*y*x'
288
+ assert str(Mul(Rational(2, 3), Rational(5, 7), evaluate=False)) == '(2/3)*(5/7)'
289
+ # For issue 14160
290
+ assert str(Mul(-2, x, Pow(Mul(y,y,evaluate=False), -1, evaluate=False),
291
+ evaluate=False)) == '-2*x/(y*y)'
292
+ # issue 21537
293
+ assert str(Mul(x, Pow(1/y, -1, evaluate=False), evaluate=False)) == 'x/(1/y)'
294
+
295
+ # Issue 24108
296
+ from sympy.core.parameters import evaluate
297
+ with evaluate(False):
298
+ assert str(Mul(Pow(Integer(2), Integer(-1)), Add(Integer(-1), Mul(Integer(-1), Integer(1))))) == "(-1 - 1*1)/2"
299
+
300
+ class CustomClass1(Expr):
301
+ is_commutative = True
302
+
303
+ class CustomClass2(Expr):
304
+ is_commutative = True
305
+ cc1 = CustomClass1()
306
+ cc2 = CustomClass2()
307
+ assert str(Rational(2)*cc1) == '2*CustomClass1()'
308
+ assert str(cc1*Rational(2)) == '2*CustomClass1()'
309
+ assert str(cc1*Float("1.5")) == '1.5*CustomClass1()'
310
+ assert str(cc2*Rational(2)) == '2*CustomClass2()'
311
+ assert str(cc2*Rational(2)*cc1) == '2*CustomClass1()*CustomClass2()'
312
+ assert str(cc1*Rational(2)*cc2) == '2*CustomClass1()*CustomClass2()'
313
+
314
+
315
+ def test_NaN():
316
+ assert str(nan) == "nan"
317
+
318
+
319
+ def test_NegativeInfinity():
320
+ assert str(-oo) == "-oo"
321
+
322
+ def test_Order():
323
+ assert str(O(x)) == "O(x)"
324
+ assert str(O(x**2)) == "O(x**2)"
325
+ assert str(O(x*y)) == "O(x*y, x, y)"
326
+ assert str(O(x, x)) == "O(x)"
327
+ assert str(O(x, (x, 0))) == "O(x)"
328
+ assert str(O(x, (x, oo))) == "O(x, (x, oo))"
329
+ assert str(O(x, x, y)) == "O(x, x, y)"
330
+ assert str(O(x, x, y)) == "O(x, x, y)"
331
+ assert str(O(x, (x, oo), (y, oo))) == "O(x, (x, oo), (y, oo))"
332
+
333
+
334
+ def test_Permutation_Cycle():
335
+ from sympy.combinatorics import Permutation, Cycle
336
+
337
+ # general principle: economically, canonically show all moved elements
338
+ # and the size of the permutation.
339
+
340
+ for p, s in [
341
+ (Cycle(),
342
+ '()'),
343
+ (Cycle(2),
344
+ '(2)'),
345
+ (Cycle(2, 1),
346
+ '(1 2)'),
347
+ (Cycle(1, 2)(5)(6, 7)(10),
348
+ '(1 2)(6 7)(10)'),
349
+ (Cycle(3, 4)(1, 2)(3, 4),
350
+ '(1 2)(4)'),
351
+ ]:
352
+ assert sstr(p) == s
353
+
354
+ for p, s in [
355
+ (Permutation([]),
356
+ 'Permutation([])'),
357
+ (Permutation([], size=1),
358
+ 'Permutation([0])'),
359
+ (Permutation([], size=2),
360
+ 'Permutation([0, 1])'),
361
+ (Permutation([], size=10),
362
+ 'Permutation([], size=10)'),
363
+ (Permutation([1, 0, 2]),
364
+ 'Permutation([1, 0, 2])'),
365
+ (Permutation([1, 0, 2, 3, 4, 5]),
366
+ 'Permutation([1, 0], size=6)'),
367
+ (Permutation([1, 0, 2, 3, 4, 5], size=10),
368
+ 'Permutation([1, 0], size=10)'),
369
+ ]:
370
+ assert sstr(p, perm_cyclic=False) == s
371
+
372
+ for p, s in [
373
+ (Permutation([]),
374
+ '()'),
375
+ (Permutation([], size=1),
376
+ '(0)'),
377
+ (Permutation([], size=2),
378
+ '(1)'),
379
+ (Permutation([], size=10),
380
+ '(9)'),
381
+ (Permutation([1, 0, 2]),
382
+ '(2)(0 1)'),
383
+ (Permutation([1, 0, 2, 3, 4, 5]),
384
+ '(5)(0 1)'),
385
+ (Permutation([1, 0, 2, 3, 4, 5], size=10),
386
+ '(9)(0 1)'),
387
+ (Permutation([0, 1, 3, 2, 4, 5], size=10),
388
+ '(9)(2 3)'),
389
+ ]:
390
+ assert sstr(p) == s
391
+
392
+
393
+ with warns_deprecated_sympy():
394
+ old_print_cyclic = Permutation.print_cyclic
395
+ Permutation.print_cyclic = False
396
+ assert sstr(Permutation([1, 0, 2])) == 'Permutation([1, 0, 2])'
397
+ Permutation.print_cyclic = old_print_cyclic
398
+
399
+ def test_Pi():
400
+ assert str(pi) == "pi"
401
+
402
+
403
+ def test_Poly():
404
+ assert str(Poly(0, x)) == "Poly(0, x, domain='ZZ')"
405
+ assert str(Poly(1, x)) == "Poly(1, x, domain='ZZ')"
406
+ assert str(Poly(x, x)) == "Poly(x, x, domain='ZZ')"
407
+
408
+ assert str(Poly(2*x + 1, x)) == "Poly(2*x + 1, x, domain='ZZ')"
409
+ assert str(Poly(2*x - 1, x)) == "Poly(2*x - 1, x, domain='ZZ')"
410
+
411
+ assert str(Poly(-1, x)) == "Poly(-1, x, domain='ZZ')"
412
+ assert str(Poly(-x, x)) == "Poly(-x, x, domain='ZZ')"
413
+
414
+ assert str(Poly(-2*x + 1, x)) == "Poly(-2*x + 1, x, domain='ZZ')"
415
+ assert str(Poly(-2*x - 1, x)) == "Poly(-2*x - 1, x, domain='ZZ')"
416
+
417
+ assert str(Poly(x - 1, x)) == "Poly(x - 1, x, domain='ZZ')"
418
+ assert str(Poly(2*x + x**5, x)) == "Poly(x**5 + 2*x, x, domain='ZZ')"
419
+
420
+ assert str(Poly(3**(2*x), 3**x)) == "Poly((3**x)**2, 3**x, domain='ZZ')"
421
+ assert str(Poly((x**2)**x)) == "Poly(((x**2)**x), (x**2)**x, domain='ZZ')"
422
+
423
+ assert str(Poly((x + y)**3, (x + y), expand=False)
424
+ ) == "Poly((x + y)**3, x + y, domain='ZZ')"
425
+ assert str(Poly((x - 1)**2, (x - 1), expand=False)
426
+ ) == "Poly((x - 1)**2, x - 1, domain='ZZ')"
427
+
428
+ assert str(
429
+ Poly(x**2 + 1 + y, x)) == "Poly(x**2 + y + 1, x, domain='ZZ[y]')"
430
+ assert str(
431
+ Poly(x**2 - 1 + y, x)) == "Poly(x**2 + y - 1, x, domain='ZZ[y]')"
432
+
433
+ assert str(Poly(x**2 + I*x, x)) == "Poly(x**2 + I*x, x, domain='ZZ_I')"
434
+ assert str(Poly(x**2 - I*x, x)) == "Poly(x**2 - I*x, x, domain='ZZ_I')"
435
+
436
+ assert str(Poly(-x*y*z + x*y - 1, x, y, z)
437
+ ) == "Poly(-x*y*z + x*y - 1, x, y, z, domain='ZZ')"
438
+ assert str(Poly(-w*x**21*y**7*z + (1 + w)*z**3 - 2*x*z + 1, x, y, z)) == \
439
+ "Poly(-w*x**21*y**7*z - 2*x*z + (w + 1)*z**3 + 1, x, y, z, domain='ZZ[w]')"
440
+
441
+ assert str(Poly(x**2 + 1, x, modulus=2)) == "Poly(x**2 + 1, x, modulus=2)"
442
+ assert str(Poly(2*x**2 + 3*x + 4, x, modulus=17)) == "Poly(2*x**2 + 3*x + 4, x, modulus=17)"
443
+
444
+
445
+ def test_PolyRing():
446
+ assert str(ring("x", ZZ, lex)[0]) == "Polynomial ring in x over ZZ with lex order"
447
+ assert str(ring("x,y", QQ, grlex)[0]) == "Polynomial ring in x, y over QQ with grlex order"
448
+ assert str(ring("x,y,z", ZZ["t"], lex)[0]) == "Polynomial ring in x, y, z over ZZ[t] with lex order"
449
+
450
+
451
+ def test_FracField():
452
+ assert str(field("x", ZZ, lex)[0]) == "Rational function field in x over ZZ with lex order"
453
+ assert str(field("x,y", QQ, grlex)[0]) == "Rational function field in x, y over QQ with grlex order"
454
+ assert str(field("x,y,z", ZZ["t"], lex)[0]) == "Rational function field in x, y, z over ZZ[t] with lex order"
455
+
456
+
457
+ def test_PolyElement():
458
+ Ruv, u,v = ring("u,v", ZZ)
459
+ Rxyz, x,y,z = ring("x,y,z", Ruv)
460
+ Rx_zzi, xz = ring("x", ZZ_I)
461
+
462
+ assert str(x - x) == "0"
463
+ assert str(x - 1) == "x - 1"
464
+ assert str(x + 1) == "x + 1"
465
+ assert str(x**2) == "x**2"
466
+ assert str(x**(-2)) == "x**(-2)"
467
+ assert str(x**QQ(1, 2)) == "x**(1/2)"
468
+
469
+ assert str((u**2 + 3*u*v + 1)*x**2*y + u + 1) == "(u**2 + 3*u*v + 1)*x**2*y + u + 1"
470
+ assert str((u**2 + 3*u*v + 1)*x**2*y + (u + 1)*x) == "(u**2 + 3*u*v + 1)*x**2*y + (u + 1)*x"
471
+ assert str((u**2 + 3*u*v + 1)*x**2*y + (u + 1)*x + 1) == "(u**2 + 3*u*v + 1)*x**2*y + (u + 1)*x + 1"
472
+ assert str((-u**2 + 3*u*v - 1)*x**2*y - (u + 1)*x - 1) == "-(u**2 - 3*u*v + 1)*x**2*y - (u + 1)*x - 1"
473
+
474
+ assert str(-(v**2 + v + 1)*x + 3*u*v + 1) == "-(v**2 + v + 1)*x + 3*u*v + 1"
475
+ assert str(-(v**2 + v + 1)*x - 3*u*v + 1) == "-(v**2 + v + 1)*x - 3*u*v + 1"
476
+
477
+ assert str((1+I)*xz + 2) == "(1 + 1*I)*x + (2 + 0*I)"
478
+
479
+
480
+ def test_FracElement():
481
+ Fuv, u,v = field("u,v", ZZ)
482
+ Fxyzt, x,y,z,t = field("x,y,z,t", Fuv)
483
+ Rx_zzi, xz = field("x", QQ_I)
484
+ i = QQ_I(0, 1)
485
+
486
+ assert str(x - x) == "0"
487
+ assert str(x - 1) == "x - 1"
488
+ assert str(x + 1) == "x + 1"
489
+
490
+ assert str(x/3) == "x/3"
491
+ assert str(x/z) == "x/z"
492
+ assert str(x*y/z) == "x*y/z"
493
+ assert str(x/(z*t)) == "x/(z*t)"
494
+ assert str(x*y/(z*t)) == "x*y/(z*t)"
495
+
496
+ assert str((x - 1)/y) == "(x - 1)/y"
497
+ assert str((x + 1)/y) == "(x + 1)/y"
498
+ assert str((-x - 1)/y) == "(-x - 1)/y"
499
+ assert str((x + 1)/(y*z)) == "(x + 1)/(y*z)"
500
+ assert str(-y/(x + 1)) == "-y/(x + 1)"
501
+ assert str(y*z/(x + 1)) == "y*z/(x + 1)"
502
+
503
+ assert str(((u + 1)*x*y + 1)/((v - 1)*z - 1)) == "((u + 1)*x*y + 1)/((v - 1)*z - 1)"
504
+ assert str(((u + 1)*x*y + 1)/((v - 1)*z - t*u*v - 1)) == "((u + 1)*x*y + 1)/((v - 1)*z - u*v*t - 1)"
505
+
506
+ assert str((1+i)/xz) == "(1 + 1*I)/x"
507
+ assert str(((1+i)*xz - i)/xz) == "((1 + 1*I)*x + (0 + -1*I))/x"
508
+
509
+
510
+ def test_GaussianInteger():
511
+ assert str(ZZ_I(1, 0)) == "1"
512
+ assert str(ZZ_I(-1, 0)) == "-1"
513
+ assert str(ZZ_I(0, 1)) == "I"
514
+ assert str(ZZ_I(0, -1)) == "-I"
515
+ assert str(ZZ_I(0, 2)) == "2*I"
516
+ assert str(ZZ_I(0, -2)) == "-2*I"
517
+ assert str(ZZ_I(1, 1)) == "1 + I"
518
+ assert str(ZZ_I(-1, -1)) == "-1 - I"
519
+ assert str(ZZ_I(-1, -2)) == "-1 - 2*I"
520
+
521
+
522
+ def test_GaussianRational():
523
+ assert str(QQ_I(1, 0)) == "1"
524
+ assert str(QQ_I(QQ(2, 3), 0)) == "2/3"
525
+ assert str(QQ_I(0, QQ(2, 3))) == "2*I/3"
526
+ assert str(QQ_I(QQ(1, 2), QQ(-2, 3))) == "1/2 - 2*I/3"
527
+
528
+
529
+ def test_Pow():
530
+ assert str(x**-1) == "1/x"
531
+ assert str(x**-2) == "x**(-2)"
532
+ assert str(x**2) == "x**2"
533
+ assert str((x + y)**-1) == "1/(x + y)"
534
+ assert str((x + y)**-2) == "(x + y)**(-2)"
535
+ assert str((x + y)**2) == "(x + y)**2"
536
+ assert str((x + y)**(1 + x)) == "(x + y)**(x + 1)"
537
+ assert str(x**Rational(1, 3)) == "x**(1/3)"
538
+ assert str(1/x**Rational(1, 3)) == "x**(-1/3)"
539
+ assert str(sqrt(sqrt(x))) == "x**(1/4)"
540
+ # not the same as x**-1
541
+ assert str(x**-1.0) == 'x**(-1.0)'
542
+ # see issue #2860
543
+ assert str(Pow(S(2), -1.0, evaluate=False)) == '2**(-1.0)'
544
+
545
+
546
+ def test_sqrt():
547
+ assert str(sqrt(x)) == "sqrt(x)"
548
+ assert str(sqrt(x**2)) == "sqrt(x**2)"
549
+ assert str(1/sqrt(x)) == "1/sqrt(x)"
550
+ assert str(1/sqrt(x**2)) == "1/sqrt(x**2)"
551
+ assert str(y/sqrt(x)) == "y/sqrt(x)"
552
+ assert str(x**0.5) == "x**0.5"
553
+ assert str(1/x**0.5) == "x**(-0.5)"
554
+
555
+
556
+ def test_Rational():
557
+ n1 = Rational(1, 4)
558
+ n2 = Rational(1, 3)
559
+ n3 = Rational(2, 4)
560
+ n4 = Rational(2, -4)
561
+ n5 = Rational(0)
562
+ n7 = Rational(3)
563
+ n8 = Rational(-3)
564
+ assert str(n1*n2) == "1/12"
565
+ assert str(n1*n2) == "1/12"
566
+ assert str(n3) == "1/2"
567
+ assert str(n1*n3) == "1/8"
568
+ assert str(n1 + n3) == "3/4"
569
+ assert str(n1 + n2) == "7/12"
570
+ assert str(n1 + n4) == "-1/4"
571
+ assert str(n4*n4) == "1/4"
572
+ assert str(n4 + n2) == "-1/6"
573
+ assert str(n4 + n5) == "-1/2"
574
+ assert str(n4*n5) == "0"
575
+ assert str(n3 + n4) == "0"
576
+ assert str(n1**n7) == "1/64"
577
+ assert str(n2**n7) == "1/27"
578
+ assert str(n2**n8) == "27"
579
+ assert str(n7**n8) == "1/27"
580
+ assert str(Rational("-25")) == "-25"
581
+ assert str(Rational("1.25")) == "5/4"
582
+ assert str(Rational("-2.6e-2")) == "-13/500"
583
+ assert str(S("25/7")) == "25/7"
584
+ assert str(S("-123/569")) == "-123/569"
585
+ assert str(S("0.1[23]", rational=1)) == "61/495"
586
+ assert str(S("5.1[666]", rational=1)) == "31/6"
587
+ assert str(S("-5.1[666]", rational=1)) == "-31/6"
588
+ assert str(S("0.[9]", rational=1)) == "1"
589
+ assert str(S("-0.[9]", rational=1)) == "-1"
590
+
591
+ assert str(sqrt(Rational(1, 4))) == "1/2"
592
+ assert str(sqrt(Rational(1, 36))) == "1/6"
593
+
594
+ assert str((123**25) ** Rational(1, 25)) == "123"
595
+ assert str((123**25 + 1)**Rational(1, 25)) != "123"
596
+ assert str((123**25 - 1)**Rational(1, 25)) != "123"
597
+ assert str((123**25 - 1)**Rational(1, 25)) != "122"
598
+
599
+ assert str(sqrt(Rational(81, 36))**3) == "27/8"
600
+ assert str(1/sqrt(Rational(81, 36))**3) == "8/27"
601
+
602
+ assert str(sqrt(-4)) == str(2*I)
603
+ assert str(2**Rational(1, 10**10)) == "2**(1/10000000000)"
604
+
605
+ assert sstr(Rational(2, 3), sympy_integers=True) == "S(2)/3"
606
+ x = Symbol("x")
607
+ assert sstr(x**Rational(2, 3), sympy_integers=True) == "x**(S(2)/3)"
608
+ assert sstr(Eq(x, Rational(2, 3)), sympy_integers=True) == "Eq(x, S(2)/3)"
609
+ assert sstr(Limit(x, x, Rational(7, 2)), sympy_integers=True) == \
610
+ "Limit(x, x, S(7)/2, dir='+')"
611
+
612
+
613
+ def test_Float():
614
+ # NOTE dps is the whole number of decimal digits
615
+ assert str(Float('1.23', dps=1 + 2)) == '1.23'
616
+ assert str(Float('1.23456789', dps=1 + 8)) == '1.23456789'
617
+ assert str(
618
+ Float('1.234567890123456789', dps=1 + 18)) == '1.234567890123456789'
619
+ assert str(pi.evalf(1 + 2)) == '3.14'
620
+ assert str(pi.evalf(1 + 14)) == '3.14159265358979'
621
+ assert str(pi.evalf(1 + 64)) == ('3.141592653589793238462643383279'
622
+ '5028841971693993751058209749445923')
623
+ assert str(pi.round(-1)) == '0.0'
624
+ assert str((pi**400 - (pi**400).round(1)).n(2)) == '-0.e+88'
625
+ assert sstr(Float("100"), full_prec=False, min=-2, max=2) == '1.0e+2'
626
+ assert sstr(Float("100"), full_prec=False, min=-2, max=3) == '100.0'
627
+ assert sstr(Float("0.1"), full_prec=False, min=-2, max=3) == '0.1'
628
+ assert sstr(Float("0.099"), min=-2, max=3) == '9.90000000000000e-2'
629
+
630
+
631
+ def test_Relational():
632
+ assert str(Rel(x, y, "<")) == "x < y"
633
+ assert str(Rel(x + y, y, "==")) == "Eq(x + y, y)"
634
+ assert str(Rel(x, y, "!=")) == "Ne(x, y)"
635
+ assert str(Eq(x, 1) | Eq(x, 2)) == "Eq(x, 1) | Eq(x, 2)"
636
+ assert str(Ne(x, 1) & Ne(x, 2)) == "Ne(x, 1) & Ne(x, 2)"
637
+
638
+
639
+ def test_AppliedBinaryRelation():
640
+ assert str(Q.eq(x, y)) == "Q.eq(x, y)"
641
+ assert str(Q.ne(x, y)) == "Q.ne(x, y)"
642
+
643
+
644
+ def test_CRootOf():
645
+ assert str(rootof(x**5 + 2*x - 1, 0)) == "CRootOf(x**5 + 2*x - 1, 0)"
646
+
647
+
648
+ def test_RootSum():
649
+ f = x**5 + 2*x - 1
650
+
651
+ assert str(
652
+ RootSum(f, Lambda(z, z), auto=False)) == "RootSum(x**5 + 2*x - 1)"
653
+ assert str(RootSum(f, Lambda(
654
+ z, z**2), auto=False)) == "RootSum(x**5 + 2*x - 1, Lambda(z, z**2))"
655
+
656
+
657
+ def test_GroebnerBasis():
658
+ assert str(groebner(
659
+ [], x, y)) == "GroebnerBasis([], x, y, domain='ZZ', order='lex')"
660
+
661
+ F = [x**2 - 3*y - x + 1, y**2 - 2*x + y - 1]
662
+
663
+ assert str(groebner(F, order='grlex')) == \
664
+ "GroebnerBasis([x**2 - x - 3*y + 1, y**2 - 2*x + y - 1], x, y, domain='ZZ', order='grlex')"
665
+ assert str(groebner(F, order='lex')) == \
666
+ "GroebnerBasis([2*x - y**2 - y + 1, y**4 + 2*y**3 - 3*y**2 - 16*y + 7], x, y, domain='ZZ', order='lex')"
667
+
668
+ def test_set():
669
+ assert sstr(set()) == 'set()'
670
+ assert sstr(frozenset()) == 'frozenset()'
671
+
672
+ assert sstr({1}) == '{1}'
673
+ assert sstr(frozenset([1])) == 'frozenset({1})'
674
+ assert sstr({1, 2, 3}) == '{1, 2, 3}'
675
+ assert sstr(frozenset([1, 2, 3])) == 'frozenset({1, 2, 3})'
676
+
677
+ assert sstr(
678
+ {1, x, x**2, x**3, x**4}) == '{1, x, x**2, x**3, x**4}'
679
+ assert sstr(
680
+ frozenset([1, x, x**2, x**3, x**4])) == 'frozenset({1, x, x**2, x**3, x**4})'
681
+
682
+
683
+ def test_SparseMatrix():
684
+ M = SparseMatrix([[x**+1, 1], [y, x + y]])
685
+ assert str(M) == "Matrix([[x, 1], [y, x + y]])"
686
+ assert sstr(M) == "Matrix([\n[x, 1],\n[y, x + y]])"
687
+
688
+
689
+ def test_Sum():
690
+ assert str(summation(cos(3*z), (z, x, y))) == "Sum(cos(3*z), (z, x, y))"
691
+ assert str(Sum(x*y**2, (x, -2, 2), (y, -5, 5))) == \
692
+ "Sum(x*y**2, (x, -2, 2), (y, -5, 5))"
693
+
694
+
695
+ def test_Symbol():
696
+ assert str(y) == "y"
697
+ assert str(x) == "x"
698
+ e = x
699
+ assert str(e) == "x"
700
+
701
+
702
+ def test_tuple():
703
+ assert str((x,)) == sstr((x,)) == "(x,)"
704
+ assert str((x + y, 1 + x)) == sstr((x + y, 1 + x)) == "(x + y, x + 1)"
705
+ assert str((x + y, (
706
+ 1 + x, x**2))) == sstr((x + y, (1 + x, x**2))) == "(x + y, (x + 1, x**2))"
707
+
708
+
709
+ def test_Series_str():
710
+ tf1 = TransferFunction(x*y**2 - z, y**3 - t**3, y)
711
+ tf2 = TransferFunction(x - y, x + y, y)
712
+ tf3 = TransferFunction(t*x**2 - t**w*x + w, t - y, y)
713
+ assert str(Series(tf1, tf2)) == \
714
+ "Series(TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y))"
715
+ assert str(Series(tf1, tf2, tf3)) == \
716
+ "Series(TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y), TransferFunction(t*x**2 - t**w*x + w, t - y, y))"
717
+ assert str(Series(-tf2, tf1)) == \
718
+ "Series(TransferFunction(-x + y, x + y, y), TransferFunction(x*y**2 - z, -t**3 + y**3, y))"
719
+
720
+
721
+ def test_MIMOSeries_str():
722
+ tf1 = TransferFunction(x*y**2 - z, y**3 - t**3, y)
723
+ tf2 = TransferFunction(x - y, x + y, y)
724
+ tfm_1 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf1]])
725
+ tfm_2 = TransferFunctionMatrix([[tf2, tf1], [tf1, tf2]])
726
+ assert str(MIMOSeries(tfm_1, tfm_2)) == \
727
+ "MIMOSeries(TransferFunctionMatrix(((TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y)), "\
728
+ "(TransferFunction(x - y, x + y, y), TransferFunction(x*y**2 - z, -t**3 + y**3, y)))), "\
729
+ "TransferFunctionMatrix(((TransferFunction(x - y, x + y, y), TransferFunction(x*y**2 - z, -t**3 + y**3, y)), "\
730
+ "(TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y)))))"
731
+
732
+
733
+ def test_TransferFunction_str():
734
+ tf1 = TransferFunction(x - 1, x + 1, x)
735
+ assert str(tf1) == "TransferFunction(x - 1, x + 1, x)"
736
+ tf2 = TransferFunction(x + 1, 2 - y, x)
737
+ assert str(tf2) == "TransferFunction(x + 1, 2 - y, x)"
738
+ tf3 = TransferFunction(y, y**2 + 2*y + 3, y)
739
+ assert str(tf3) == "TransferFunction(y, y**2 + 2*y + 3, y)"
740
+
741
+
742
+ def test_Parallel_str():
743
+ tf1 = TransferFunction(x*y**2 - z, y**3 - t**3, y)
744
+ tf2 = TransferFunction(x - y, x + y, y)
745
+ tf3 = TransferFunction(t*x**2 - t**w*x + w, t - y, y)
746
+ assert str(Parallel(tf1, tf2)) == \
747
+ "Parallel(TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y))"
748
+ assert str(Parallel(tf1, tf2, tf3)) == \
749
+ "Parallel(TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y), TransferFunction(t*x**2 - t**w*x + w, t - y, y))"
750
+ assert str(Parallel(-tf2, tf1)) == \
751
+ "Parallel(TransferFunction(-x + y, x + y, y), TransferFunction(x*y**2 - z, -t**3 + y**3, y))"
752
+
753
+
754
+ def test_MIMOParallel_str():
755
+ tf1 = TransferFunction(x*y**2 - z, y**3 - t**3, y)
756
+ tf2 = TransferFunction(x - y, x + y, y)
757
+ tfm_1 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf1]])
758
+ tfm_2 = TransferFunctionMatrix([[tf2, tf1], [tf1, tf2]])
759
+ assert str(MIMOParallel(tfm_1, tfm_2)) == \
760
+ "MIMOParallel(TransferFunctionMatrix(((TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y)), "\
761
+ "(TransferFunction(x - y, x + y, y), TransferFunction(x*y**2 - z, -t**3 + y**3, y)))), "\
762
+ "TransferFunctionMatrix(((TransferFunction(x - y, x + y, y), TransferFunction(x*y**2 - z, -t**3 + y**3, y)), "\
763
+ "(TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y)))))"
764
+
765
+
766
+ def test_Feedback_str():
767
+ tf1 = TransferFunction(x*y**2 - z, y**3 - t**3, y)
768
+ tf2 = TransferFunction(x - y, x + y, y)
769
+ tf3 = TransferFunction(t*x**2 - t**w*x + w, t - y, y)
770
+ assert str(Feedback(tf1*tf2, tf3)) == \
771
+ "Feedback(Series(TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y)), " \
772
+ "TransferFunction(t*x**2 - t**w*x + w, t - y, y), -1)"
773
+ assert str(Feedback(tf1, TransferFunction(1, 1, y), 1)) == \
774
+ "Feedback(TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(1, 1, y), 1)"
775
+
776
+
777
+ def test_MIMOFeedback_str():
778
+ tf1 = TransferFunction(x**2 - y**3, y - z, x)
779
+ tf2 = TransferFunction(y - x, z + y, x)
780
+ tfm_1 = TransferFunctionMatrix([[tf2, tf1], [tf1, tf2]])
781
+ tfm_2 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf1]])
782
+ assert (str(MIMOFeedback(tfm_1, tfm_2)) \
783
+ == "MIMOFeedback(TransferFunctionMatrix(((TransferFunction(-x + y, y + z, x), TransferFunction(x**2 - y**3, y - z, x))," \
784
+ " (TransferFunction(x**2 - y**3, y - z, x), TransferFunction(-x + y, y + z, x)))), " \
785
+ "TransferFunctionMatrix(((TransferFunction(x**2 - y**3, y - z, x), " \
786
+ "TransferFunction(-x + y, y + z, x)), (TransferFunction(-x + y, y + z, x), TransferFunction(x**2 - y**3, y - z, x)))), -1)")
787
+ assert (str(MIMOFeedback(tfm_1, tfm_2, 1)) \
788
+ == "MIMOFeedback(TransferFunctionMatrix(((TransferFunction(-x + y, y + z, x), TransferFunction(x**2 - y**3, y - z, x)), " \
789
+ "(TransferFunction(x**2 - y**3, y - z, x), TransferFunction(-x + y, y + z, x)))), " \
790
+ "TransferFunctionMatrix(((TransferFunction(x**2 - y**3, y - z, x), TransferFunction(-x + y, y + z, x)), "\
791
+ "(TransferFunction(-x + y, y + z, x), TransferFunction(x**2 - y**3, y - z, x)))), 1)")
792
+
793
+
794
+ def test_TransferFunctionMatrix_str():
795
+ tf1 = TransferFunction(x*y**2 - z, y**3 - t**3, y)
796
+ tf2 = TransferFunction(x - y, x + y, y)
797
+ tf3 = TransferFunction(t*x**2 - t**w*x + w, t - y, y)
798
+ assert str(TransferFunctionMatrix([[tf1], [tf2]])) == \
799
+ "TransferFunctionMatrix(((TransferFunction(x*y**2 - z, -t**3 + y**3, y),), (TransferFunction(x - y, x + y, y),)))"
800
+ assert str(TransferFunctionMatrix([[tf1, tf2], [tf3, tf2]])) == \
801
+ "TransferFunctionMatrix(((TransferFunction(x*y**2 - z, -t**3 + y**3, y), TransferFunction(x - y, x + y, y)), (TransferFunction(t*x**2 - t**w*x + w, t - y, y), TransferFunction(x - y, x + y, y))))"
802
+
803
+
804
+ def test_Quaternion_str_printer():
805
+ q = Quaternion(x, y, z, t)
806
+ assert str(q) == "x + y*i + z*j + t*k"
807
+ q = Quaternion(x,y,z,x*t)
808
+ assert str(q) == "x + y*i + z*j + t*x*k"
809
+ q = Quaternion(x,y,z,x+t)
810
+ assert str(q) == "x + y*i + z*j + (t + x)*k"
811
+
812
+
813
+ def test_Quantity_str():
814
+ assert sstr(second, abbrev=True) == "s"
815
+ assert sstr(joule, abbrev=True) == "J"
816
+ assert str(second) == "second"
817
+ assert str(joule) == "joule"
818
+
819
+
820
+ def test_wild_str():
821
+ # Check expressions containing Wild not causing infinite recursion
822
+ w = Wild('x')
823
+ assert str(w + 1) == 'x_ + 1'
824
+ assert str(exp(2**w) + 5) == 'exp(2**x_) + 5'
825
+ assert str(3*w + 1) == '3*x_ + 1'
826
+ assert str(1/w + 1) == '1 + 1/x_'
827
+ assert str(w**2 + 1) == 'x_**2 + 1'
828
+ assert str(1/(1 - w)) == '1/(1 - x_)'
829
+
830
+
831
+ def test_wild_matchpy():
832
+ from sympy.utilities.matchpy_connector import WildDot, WildPlus, WildStar
833
+
834
+ matchpy = import_module("matchpy")
835
+
836
+ if matchpy is None:
837
+ return
838
+
839
+ wd = WildDot('w_')
840
+ wp = WildPlus('w__')
841
+ ws = WildStar('w___')
842
+
843
+ assert str(wd) == 'w_'
844
+ assert str(wp) == 'w__'
845
+ assert str(ws) == 'w___'
846
+
847
+ assert str(wp/ws + 2**wd) == '2**w_ + w__/w___'
848
+ assert str(sin(wd)*cos(wp)*sqrt(ws)) == 'sqrt(w___)*sin(w_)*cos(w__)'
849
+
850
+
851
+ def test_zeta():
852
+ assert str(zeta(3)) == "zeta(3)"
853
+
854
+
855
+ def test_issue_3101():
856
+ e = x - y
857
+ a = str(e)
858
+ b = str(e)
859
+ assert a == b
860
+
861
+
862
+ def test_issue_3103():
863
+ e = -2*sqrt(x) - y/sqrt(x)/2
864
+ assert str(e) not in ["(-2)*x**1/2(-1/2)*x**(-1/2)*y",
865
+ "-2*x**1/2(-1/2)*x**(-1/2)*y", "-2*x**1/2-1/2*x**-1/2*w"]
866
+ assert str(e) == "-2*sqrt(x) - y/(2*sqrt(x))"
867
+
868
+
869
+ def test_issue_4021():
870
+ e = Integral(x, x) + 1
871
+ assert str(e) == 'Integral(x, x) + 1'
872
+
873
+
874
+ def test_sstrrepr():
875
+ assert sstr('abc') == 'abc'
876
+ assert sstrrepr('abc') == "'abc'"
877
+
878
+ e = ['a', 'b', 'c', x]
879
+ assert sstr(e) == "[a, b, c, x]"
880
+ assert sstrrepr(e) == "['a', 'b', 'c', x]"
881
+
882
+
883
+ def test_infinity():
884
+ assert sstr(oo*I) == "oo*I"
885
+
886
+
887
+ def test_full_prec():
888
+ assert sstr(S("0.3"), full_prec=True) == "0.300000000000000"
889
+ assert sstr(S("0.3"), full_prec="auto") == "0.300000000000000"
890
+ assert sstr(S("0.3"), full_prec=False) == "0.3"
891
+ assert sstr(S("0.3")*x, full_prec=True) in [
892
+ "0.300000000000000*x",
893
+ "x*0.300000000000000"
894
+ ]
895
+ assert sstr(S("0.3")*x, full_prec="auto") in [
896
+ "0.3*x",
897
+ "x*0.3"
898
+ ]
899
+ assert sstr(S("0.3")*x, full_prec=False) in [
900
+ "0.3*x",
901
+ "x*0.3"
902
+ ]
903
+
904
+
905
+ def test_noncommutative():
906
+ A, B, C = symbols('A,B,C', commutative=False)
907
+
908
+ assert sstr(A*B*C**-1) == "A*B*C**(-1)"
909
+ assert sstr(C**-1*A*B) == "C**(-1)*A*B"
910
+ assert sstr(A*C**-1*B) == "A*C**(-1)*B"
911
+ assert sstr(sqrt(A)) == "sqrt(A)"
912
+ assert sstr(1/sqrt(A)) == "A**(-1/2)"
913
+
914
+
915
+ def test_empty_printer():
916
+ str_printer = StrPrinter()
917
+ assert str_printer.emptyPrinter("foo") == "foo"
918
+ assert str_printer.emptyPrinter(x*y) == "x*y"
919
+ assert str_printer.emptyPrinter(32) == "32"
920
+
921
+
922
+ def test_settings():
923
+ raises(TypeError, lambda: sstr(S(4), method="garbage"))
924
+
925
+
926
+ def test_RandomDomain():
927
+ from sympy.stats import Normal, Die, Exponential, pspace, where
928
+ X = Normal('x1', 0, 1)
929
+ assert str(where(X > 0)) == "Domain: (0 < x1) & (x1 < oo)"
930
+
931
+ D = Die('d1', 6)
932
+ assert str(where(D > 4)) == "Domain: Eq(d1, 5) | Eq(d1, 6)"
933
+
934
+ A = Exponential('a', 1)
935
+ B = Exponential('b', 1)
936
+ assert str(pspace(Tuple(A, B)).domain) == "Domain: (0 <= a) & (0 <= b) & (a < oo) & (b < oo)"
937
+
938
+
939
+ def test_FiniteSet():
940
+ assert str(FiniteSet(*range(1, 51))) == (
941
+ '{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,'
942
+ ' 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,'
943
+ ' 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50}'
944
+ )
945
+ assert str(FiniteSet(*range(1, 6))) == '{1, 2, 3, 4, 5}'
946
+ assert str(FiniteSet(*[x*y, x**2])) == '{x**2, x*y}'
947
+ assert str(FiniteSet(FiniteSet(FiniteSet(x, y), 5), FiniteSet(x,y), 5)
948
+ ) == 'FiniteSet(5, FiniteSet(5, {x, y}), {x, y})'
949
+
950
+
951
+ def test_Partition():
952
+ assert str(Partition(FiniteSet(x, y), {z})) == 'Partition({z}, {x, y})'
953
+
954
+ def test_UniversalSet():
955
+ assert str(S.UniversalSet) == 'UniversalSet'
956
+
957
+
958
+ def test_PrettyPoly():
959
+ F = QQ.frac_field(x, y)
960
+ R = QQ[x, y]
961
+ assert sstr(F.convert(x/(x + y))) == sstr(x/(x + y))
962
+ assert sstr(R.convert(x + y)) == sstr(x + y)
963
+
964
+
965
+ def test_categories():
966
+ from sympy.categories import (Object, NamedMorphism,
967
+ IdentityMorphism, Category)
968
+
969
+ A = Object("A")
970
+ B = Object("B")
971
+
972
+ f = NamedMorphism(A, B, "f")
973
+ id_A = IdentityMorphism(A)
974
+
975
+ K = Category("K")
976
+
977
+ assert str(A) == 'Object("A")'
978
+ assert str(f) == 'NamedMorphism(Object("A"), Object("B"), "f")'
979
+ assert str(id_A) == 'IdentityMorphism(Object("A"))'
980
+
981
+ assert str(K) == 'Category("K")'
982
+
983
+
984
+ def test_Tr():
985
+ A, B = symbols('A B', commutative=False)
986
+ t = Tr(A*B)
987
+ assert str(t) == 'Tr(A*B)'
988
+
989
+
990
+ def test_issue_6387():
991
+ assert str(factor(-3.0*z + 3)) == '-3.0*(1.0*z - 1.0)'
992
+
993
+
994
+ def test_MatMul_MatAdd():
995
+ X, Y = MatrixSymbol("X", 2, 2), MatrixSymbol("Y", 2, 2)
996
+ assert str(2*(X + Y)) == "2*X + 2*Y"
997
+
998
+ assert str(I*X) == "I*X"
999
+ assert str(-I*X) == "-I*X"
1000
+ assert str((1 + I)*X) == '(1 + I)*X'
1001
+ assert str(-(1 + I)*X) == '(-1 - I)*X'
1002
+ assert str(MatAdd(MatAdd(X, Y), MatAdd(X, Y))) == '(X + Y) + (X + Y)'
1003
+
1004
+
1005
+ def test_MatrixSlice():
1006
+ n = Symbol('n', integer=True)
1007
+ X = MatrixSymbol('X', n, n)
1008
+ Y = MatrixSymbol('Y', 10, 10)
1009
+ Z = MatrixSymbol('Z', 10, 10)
1010
+
1011
+ assert str(MatrixSlice(X, (None, None, None), (None, None, None))) == 'X[:, :]'
1012
+ assert str(X[x:x + 1, y:y + 1]) == 'X[x:x + 1, y:y + 1]'
1013
+ assert str(X[x:x + 1:2, y:y + 1:2]) == 'X[x:x + 1:2, y:y + 1:2]'
1014
+ assert str(X[:x, y:]) == 'X[:x, y:]'
1015
+ assert str(X[:x, y:]) == 'X[:x, y:]'
1016
+ assert str(X[x:, :y]) == 'X[x:, :y]'
1017
+ assert str(X[x:y, z:w]) == 'X[x:y, z:w]'
1018
+ assert str(X[x:y:t, w:t:x]) == 'X[x:y:t, w:t:x]'
1019
+ assert str(X[x::y, t::w]) == 'X[x::y, t::w]'
1020
+ assert str(X[:x:y, :t:w]) == 'X[:x:y, :t:w]'
1021
+ assert str(X[::x, ::y]) == 'X[::x, ::y]'
1022
+ assert str(MatrixSlice(X, (0, None, None), (0, None, None))) == 'X[:, :]'
1023
+ assert str(MatrixSlice(X, (None, n, None), (None, n, None))) == 'X[:, :]'
1024
+ assert str(MatrixSlice(X, (0, n, None), (0, n, None))) == 'X[:, :]'
1025
+ assert str(MatrixSlice(X, (0, n, 2), (0, n, 2))) == 'X[::2, ::2]'
1026
+ assert str(X[1:2:3, 4:5:6]) == 'X[1:2:3, 4:5:6]'
1027
+ assert str(X[1:3:5, 4:6:8]) == 'X[1:3:5, 4:6:8]'
1028
+ assert str(X[1:10:2]) == 'X[1:10:2, :]'
1029
+ assert str(Y[:5, 1:9:2]) == 'Y[:5, 1:9:2]'
1030
+ assert str(Y[:5, 1:10:2]) == 'Y[:5, 1::2]'
1031
+ assert str(Y[5, :5:2]) == 'Y[5:6, :5:2]'
1032
+ assert str(X[0:1, 0:1]) == 'X[:1, :1]'
1033
+ assert str(X[0:1:2, 0:1:2]) == 'X[:1:2, :1:2]'
1034
+ assert str((Y + Z)[2:, 2:]) == '(Y + Z)[2:, 2:]'
1035
+
1036
+ def test_true_false():
1037
+ assert str(true) == repr(true) == sstr(true) == "True"
1038
+ assert str(false) == repr(false) == sstr(false) == "False"
1039
+
1040
+ def test_Equivalent():
1041
+ assert str(Equivalent(y, x)) == "Equivalent(x, y)"
1042
+
1043
+ def test_Xor():
1044
+ assert str(Xor(y, x, evaluate=False)) == "x ^ y"
1045
+
1046
+ def test_Complement():
1047
+ assert str(Complement(S.Reals, S.Naturals)) == 'Complement(Reals, Naturals)'
1048
+
1049
+ def test_SymmetricDifference():
1050
+ assert str(SymmetricDifference(Interval(2, 3), Interval(3, 4),evaluate=False)) == \
1051
+ 'SymmetricDifference(Interval(2, 3), Interval(3, 4))'
1052
+
1053
+
1054
+ def test_UnevaluatedExpr():
1055
+ a, b = symbols("a b")
1056
+ expr1 = 2*UnevaluatedExpr(a+b)
1057
+ assert str(expr1) == "2*(a + b)"
1058
+
1059
+
1060
+ def test_MatrixElement_printing():
1061
+ # test cases for issue #11821
1062
+ A = MatrixSymbol("A", 1, 3)
1063
+ B = MatrixSymbol("B", 1, 3)
1064
+ C = MatrixSymbol("C", 1, 3)
1065
+
1066
+ assert(str(A[0, 0]) == "A[0, 0]")
1067
+ assert(str(3 * A[0, 0]) == "3*A[0, 0]")
1068
+
1069
+ F = C[0, 0].subs(C, A - B)
1070
+ assert str(F) == "(A - B)[0, 0]"
1071
+
1072
+
1073
+ def test_MatrixSymbol_printing():
1074
+ A = MatrixSymbol("A", 3, 3)
1075
+ B = MatrixSymbol("B", 3, 3)
1076
+
1077
+ assert str(A - A*B - B) == "A - A*B - B"
1078
+ assert str(A*B - (A+B)) == "-A + A*B - B"
1079
+ assert str(A**(-1)) == "A**(-1)"
1080
+ assert str(A**3) == "A**3"
1081
+
1082
+
1083
+ def test_MatrixExpressions():
1084
+ n = Symbol('n', integer=True)
1085
+ X = MatrixSymbol('X', n, n)
1086
+
1087
+ assert str(X) == "X"
1088
+
1089
+ # Apply function elementwise (`ElementwiseApplyFunc`):
1090
+
1091
+ expr = (X.T*X).applyfunc(sin)
1092
+ assert str(expr) == 'Lambda(_d, sin(_d)).(X.T*X)'
1093
+
1094
+ lamda = Lambda(x, 1/x)
1095
+ expr = (n*X).applyfunc(lamda)
1096
+ assert str(expr) == 'Lambda(x, 1/x).(n*X)'
1097
+
1098
+
1099
+ def test_Subs_printing():
1100
+ assert str(Subs(x, (x,), (1,))) == 'Subs(x, x, 1)'
1101
+ assert str(Subs(x + y, (x, y), (1, 2))) == 'Subs(x + y, (x, y), (1, 2))'
1102
+
1103
+
1104
+ def test_issue_15716():
1105
+ e = Integral(factorial(x), (x, -oo, oo))
1106
+ assert e.as_terms() == ([(e, ((1.0, 0.0), (1,), ()))], [e])
1107
+
1108
+
1109
+ def test_str_special_matrices():
1110
+ from sympy.matrices import Identity, ZeroMatrix, OneMatrix
1111
+ assert str(Identity(4)) == 'I'
1112
+ assert str(ZeroMatrix(2, 2)) == '0'
1113
+ assert str(OneMatrix(2, 2)) == '1'
1114
+
1115
+
1116
+ def test_issue_14567():
1117
+ assert factorial(Sum(-1, (x, 0, 0))) + y # doesn't raise an error
1118
+
1119
+
1120
+ def test_issue_21823():
1121
+ assert str(Partition([1, 2])) == 'Partition({1, 2})'
1122
+ assert str(Partition({1, 2})) == 'Partition({1, 2})'
1123
+
1124
+
1125
+ def test_issue_22689():
1126
+ assert str(Mul(Pow(x,-2, evaluate=False), Pow(3,-1,evaluate=False), evaluate=False)) == "1/(x**2*3)"
1127
+
1128
+
1129
+ def test_issue_21119_21460():
1130
+ ss = lambda x: str(S(x, evaluate=False))
1131
+ assert ss('4/2') == '4/2'
1132
+ assert ss('4/-2') == '4/(-2)'
1133
+ assert ss('-4/2') == '-4/2'
1134
+ assert ss('-4/-2') == '-4/(-2)'
1135
+ assert ss('-2*3/-1') == '-2*3/(-1)'
1136
+ assert ss('-2*3/-1/2') == '-2*3/(-1*2)'
1137
+ assert ss('4/2/1') == '4/(2*1)'
1138
+ assert ss('-2/-1/2') == '-2/(-1*2)'
1139
+ assert ss('2*3*4**(-2*3)') == '2*3/4**(2*3)'
1140
+ assert ss('2*3*1*4**(-2*3)') == '2*3*1/4**(2*3)'
1141
+
1142
+
1143
+ def test_Str():
1144
+ from sympy.core.symbol import Str
1145
+ assert str(Str('x')) == 'x'
1146
+ assert sstrrepr(Str('x')) == "Str('x')"
1147
+
1148
+
1149
+ def test_diffgeom():
1150
+ from sympy.diffgeom import Manifold, Patch, CoordSystem, BaseScalarField
1151
+ x,y = symbols('x y', real=True)
1152
+ m = Manifold('M', 2)
1153
+ assert str(m) == "M"
1154
+ p = Patch('P', m)
1155
+ assert str(p) == "P"
1156
+ rect = CoordSystem('rect', p, [x, y])
1157
+ assert str(rect) == "rect"
1158
+ b = BaseScalarField(rect, 0)
1159
+ assert str(b) == "x"
1160
+
1161
+ def test_NDimArray():
1162
+ assert sstr(NDimArray(1.0), full_prec=True) == '1.00000000000000'
1163
+ assert sstr(NDimArray(1.0), full_prec=False) == '1.0'
1164
+ assert sstr(NDimArray([1.0, 2.0]), full_prec=True) == '[1.00000000000000, 2.00000000000000]'
1165
+ assert sstr(NDimArray([1.0, 2.0]), full_prec=False) == '[1.0, 2.0]'
1166
+
1167
+ def test_Predicate():
1168
+ assert sstr(Q.even) == 'Q.even'
1169
+
1170
+ def test_AppliedPredicate():
1171
+ assert sstr(Q.even(x)) == 'Q.even(x)'
1172
+
1173
+ def test_printing_str_array_expressions():
1174
+ assert sstr(ArraySymbol("A", (2, 3, 4))) == "A"
1175
+ assert sstr(ArrayElement("A", (2, 1/(1-x), 0))) == "A[2, 1/(1 - x), 0]"
1176
+ M = MatrixSymbol("M", 3, 3)
1177
+ N = MatrixSymbol("N", 3, 3)
1178
+ assert sstr(ArrayElement(M*N, [x, 0])) == "(M*N)[x, 0]"
1179
+
1180
+ def test_printing_stats():
1181
+ # issue 24132
1182
+ x = RandomSymbol("x")
1183
+ y = RandomSymbol("y")
1184
+ z1 = Probability(x > 0)*Identity(2)
1185
+ z2 = Expectation(x)*Identity(2)
1186
+ z3 = Variance(x)*Identity(2)
1187
+ z4 = Covariance(x, y) * Identity(2)
1188
+
1189
+ assert str(z1) == "Probability(x > 0)*I"
1190
+ assert str(z2) == "Expectation(x)*I"
1191
+ assert str(z3) == "Variance(x)*I"
1192
+ assert str(z4) == "Covariance(x, y)*I"
1193
+ assert z1.is_commutative == False
1194
+ assert z2.is_commutative == False
1195
+ assert z3.is_commutative == False
1196
+ assert z4.is_commutative == False
1197
+ assert z2._eval_is_commutative() == False
1198
+ assert z3._eval_is_commutative() == False
1199
+ assert z4._eval_is_commutative() == False
lib/python3.12/site-packages/sympy/printing/tests/test_tree.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.printing.tree import tree
2
+ from sympy.testing.pytest import XFAIL
3
+
4
+
5
+ # Remove this flag after making _assumptions cache deterministic.
6
+ @XFAIL
7
+ def test_print_tree_MatAdd():
8
+ from sympy.matrices.expressions import MatrixSymbol
9
+ A = MatrixSymbol('A', 3, 3)
10
+ B = MatrixSymbol('B', 3, 3)
11
+
12
+ test_str = [
13
+ 'MatAdd: A + B\n',
14
+ 'algebraic: False\n',
15
+ 'commutative: False\n',
16
+ 'complex: False\n',
17
+ 'composite: False\n',
18
+ 'even: False\n',
19
+ 'extended_negative: False\n',
20
+ 'extended_nonnegative: False\n',
21
+ 'extended_nonpositive: False\n',
22
+ 'extended_nonzero: False\n',
23
+ 'extended_positive: False\n',
24
+ 'extended_real: False\n',
25
+ 'imaginary: False\n',
26
+ 'integer: False\n',
27
+ 'irrational: False\n',
28
+ 'negative: False\n',
29
+ 'noninteger: False\n',
30
+ 'nonnegative: False\n',
31
+ 'nonpositive: False\n',
32
+ 'nonzero: False\n',
33
+ 'odd: False\n',
34
+ 'positive: False\n',
35
+ 'prime: False\n',
36
+ 'rational: False\n',
37
+ 'real: False\n',
38
+ 'transcendental: False\n',
39
+ 'zero: False\n',
40
+ '+-MatrixSymbol: A\n',
41
+ '| algebraic: False\n',
42
+ '| commutative: False\n',
43
+ '| complex: False\n',
44
+ '| composite: False\n',
45
+ '| even: False\n',
46
+ '| extended_negative: False\n',
47
+ '| extended_nonnegative: False\n',
48
+ '| extended_nonpositive: False\n',
49
+ '| extended_nonzero: False\n',
50
+ '| extended_positive: False\n',
51
+ '| extended_real: False\n',
52
+ '| imaginary: False\n',
53
+ '| integer: False\n',
54
+ '| irrational: False\n',
55
+ '| negative: False\n',
56
+ '| noninteger: False\n',
57
+ '| nonnegative: False\n',
58
+ '| nonpositive: False\n',
59
+ '| nonzero: False\n',
60
+ '| odd: False\n',
61
+ '| positive: False\n',
62
+ '| prime: False\n',
63
+ '| rational: False\n',
64
+ '| real: False\n',
65
+ '| transcendental: False\n',
66
+ '| zero: False\n',
67
+ '| +-Symbol: A\n',
68
+ '| | commutative: True\n',
69
+ '| +-Integer: 3\n',
70
+ '| | algebraic: True\n',
71
+ '| | commutative: True\n',
72
+ '| | complex: True\n',
73
+ '| | extended_negative: False\n',
74
+ '| | extended_nonnegative: True\n',
75
+ '| | extended_real: True\n',
76
+ '| | finite: True\n',
77
+ '| | hermitian: True\n',
78
+ '| | imaginary: False\n',
79
+ '| | infinite: False\n',
80
+ '| | integer: True\n',
81
+ '| | irrational: False\n',
82
+ '| | negative: False\n',
83
+ '| | noninteger: False\n',
84
+ '| | nonnegative: True\n',
85
+ '| | rational: True\n',
86
+ '| | real: True\n',
87
+ '| | transcendental: False\n',
88
+ '| +-Integer: 3\n',
89
+ '| algebraic: True\n',
90
+ '| commutative: True\n',
91
+ '| complex: True\n',
92
+ '| extended_negative: False\n',
93
+ '| extended_nonnegative: True\n',
94
+ '| extended_real: True\n',
95
+ '| finite: True\n',
96
+ '| hermitian: True\n',
97
+ '| imaginary: False\n',
98
+ '| infinite: False\n',
99
+ '| integer: True\n',
100
+ '| irrational: False\n',
101
+ '| negative: False\n',
102
+ '| noninteger: False\n',
103
+ '| nonnegative: True\n',
104
+ '| rational: True\n',
105
+ '| real: True\n',
106
+ '| transcendental: False\n',
107
+ '+-MatrixSymbol: B\n',
108
+ ' algebraic: False\n',
109
+ ' commutative: False\n',
110
+ ' complex: False\n',
111
+ ' composite: False\n',
112
+ ' even: False\n',
113
+ ' extended_negative: False\n',
114
+ ' extended_nonnegative: False\n',
115
+ ' extended_nonpositive: False\n',
116
+ ' extended_nonzero: False\n',
117
+ ' extended_positive: False\n',
118
+ ' extended_real: False\n',
119
+ ' imaginary: False\n',
120
+ ' integer: False\n',
121
+ ' irrational: False\n',
122
+ ' negative: False\n',
123
+ ' noninteger: False\n',
124
+ ' nonnegative: False\n',
125
+ ' nonpositive: False\n',
126
+ ' nonzero: False\n',
127
+ ' odd: False\n',
128
+ ' positive: False\n',
129
+ ' prime: False\n',
130
+ ' rational: False\n',
131
+ ' real: False\n',
132
+ ' transcendental: False\n',
133
+ ' zero: False\n',
134
+ ' +-Symbol: B\n',
135
+ ' | commutative: True\n',
136
+ ' +-Integer: 3\n',
137
+ ' | algebraic: True\n',
138
+ ' | commutative: True\n',
139
+ ' | complex: True\n',
140
+ ' | extended_negative: False\n',
141
+ ' | extended_nonnegative: True\n',
142
+ ' | extended_real: True\n',
143
+ ' | finite: True\n',
144
+ ' | hermitian: True\n',
145
+ ' | imaginary: False\n',
146
+ ' | infinite: False\n',
147
+ ' | integer: True\n',
148
+ ' | irrational: False\n',
149
+ ' | negative: False\n',
150
+ ' | noninteger: False\n',
151
+ ' | nonnegative: True\n',
152
+ ' | rational: True\n',
153
+ ' | real: True\n',
154
+ ' | transcendental: False\n',
155
+ ' +-Integer: 3\n',
156
+ ' algebraic: True\n',
157
+ ' commutative: True\n',
158
+ ' complex: True\n',
159
+ ' extended_negative: False\n',
160
+ ' extended_nonnegative: True\n',
161
+ ' extended_real: True\n',
162
+ ' finite: True\n',
163
+ ' hermitian: True\n',
164
+ ' imaginary: False\n',
165
+ ' infinite: False\n',
166
+ ' integer: True\n',
167
+ ' irrational: False\n',
168
+ ' negative: False\n',
169
+ ' noninteger: False\n',
170
+ ' nonnegative: True\n',
171
+ ' rational: True\n',
172
+ ' real: True\n',
173
+ ' transcendental: False\n'
174
+ ]
175
+
176
+ assert tree(A + B) == "".join(test_str)
177
+
178
+
179
+ def test_print_tree_MatAdd_noassumptions():
180
+ from sympy.matrices.expressions import MatrixSymbol
181
+ A = MatrixSymbol('A', 3, 3)
182
+ B = MatrixSymbol('B', 3, 3)
183
+
184
+ test_str = \
185
+ """MatAdd: A + B
186
+ +-MatrixSymbol: A
187
+ | +-Str: A
188
+ | +-Integer: 3
189
+ | +-Integer: 3
190
+ +-MatrixSymbol: B
191
+ +-Str: B
192
+ +-Integer: 3
193
+ +-Integer: 3
194
+ """
195
+
196
+ assert tree(A + B, assumptions=False) == test_str