passagemath-fricas 10.5.32__cp313-cp313-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ # sage_setup: distribution = sagemath-fricas
@@ -0,0 +1 @@
1
+ # sage_setup: distribution = sagemath-fricas
@@ -0,0 +1,201 @@
1
+ # sage_setup: distribution = sagemath-fricas
2
+ r"""
3
+ Conversion of symbolic expressions to FriCAS
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2018-2021 Martin Rubey
7
+ # 2021 Marius Gerbershagen
8
+ # 2024 Dima Pasechnik
9
+ #
10
+ # This program is free software: you can redistribute it and/or modify
11
+ # it under the terms of the GNU General Public License as published by
12
+ # the Free Software Foundation, either version 2 of the License, or
13
+ # (at your option) any later version.
14
+ # https://www.gnu.org/licenses/
15
+ # ****************************************************************************
16
+
17
+ from sage.rings.number_field.number_field_element_base import NumberFieldElement_base
18
+ from sage.structure.element import Expression
19
+ from sage.symbolic.expression_conversions import InterfaceInit
20
+ from sage.symbolic.ring import SR
21
+
22
+
23
+ class FriCASConverter(InterfaceInit):
24
+ """
25
+ Convert any expression to FriCAS.
26
+
27
+ EXAMPLES::
28
+
29
+ sage: var('x,y')
30
+ (x, y)
31
+ sage: f = exp(x^2) - arcsin(pi+x)/y
32
+ sage: f._fricas_() # optional - fricas
33
+ 2
34
+ x
35
+ y %e - asin(x + %pi)
36
+ ----------------------
37
+ y
38
+ """
39
+ def __init__(self):
40
+ import sage.interfaces.fricas
41
+ super().__init__(sage.interfaces.fricas.fricas)
42
+
43
+ def pyobject(self, ex, obj):
44
+ r"""
45
+ Return a string which, when evaluated by FriCAS, returns the
46
+ object as an expression.
47
+
48
+ We explicitly add the coercion to the FriCAS domains
49
+ `Expression Integer` and `Expression Complex Integer` to make
50
+ sure that elements of the symbolic ring are translated to
51
+ these. In particular, this is needed for integration, see
52
+ :issue:`28641` and :issue:`28647`.
53
+
54
+ EXAMPLES::
55
+
56
+ sage: 2._fricas_().domainOf() # optional - fricas
57
+ PositiveInteger...
58
+
59
+ sage: (-1/2)._fricas_().domainOf() # optional - fricas
60
+ Fraction(Integer...)
61
+
62
+ sage: SR(2)._fricas_().domainOf() # optional - fricas
63
+ Expression(Integer...)
64
+
65
+ sage: (sqrt(2))._fricas_().domainOf() # optional - fricas
66
+ Expression(Integer...)
67
+
68
+ sage: pi._fricas_().domainOf() # optional - fricas
69
+ Pi...
70
+
71
+ sage: asin(pi)._fricas_() # optional - fricas
72
+ asin(%pi)
73
+
74
+ sage: I._fricas_().domainOf() # optional - fricas
75
+ Complex(Integer...)
76
+
77
+ sage: SR(I)._fricas_().domainOf() # optional - fricas
78
+ Expression(Complex(Integer...))
79
+
80
+ sage: ex = (I+sqrt(2)+2)
81
+ sage: ex._fricas_().domainOf() # optional - fricas
82
+ Expression(Complex(Integer...))
83
+
84
+ sage: ex._fricas_()^2 # optional - fricas
85
+ +-+
86
+ (4 + 2 %i)\|2 + 5 + 4 %i
87
+
88
+ sage: (ex^2)._fricas_() # optional - fricas
89
+ +-+
90
+ (4 + 2 %i)\|2 + 5 + 4 %i
91
+ """
92
+ try:
93
+ result = getattr(obj, self.name_init)()
94
+ except AttributeError:
95
+ result = repr(obj)
96
+ else:
97
+ if isinstance(obj, NumberFieldElement_base):
98
+ from sage.rings.number_field.number_field_element_quadratic import NumberFieldElement_gaussian
99
+ if isinstance(obj, NumberFieldElement_gaussian):
100
+ return "((%s)::EXPR COMPLEX INT)" % result
101
+ return "((%s)::EXPR INT)" % result
102
+
103
+ def symbol(self, ex):
104
+ """
105
+ Convert the argument, which is a symbol, to FriCAS.
106
+
107
+ In this case, we do not return an `Expression Integer`,
108
+ because FriCAS frequently requires elements of domain
109
+ `Symbol` or `Variable` as arguments, for example to
110
+ `integrate`. Moreover, FriCAS is able to do the conversion
111
+ itself, whenever the argument should be interpreted as a
112
+ symbolic expression.
113
+
114
+ EXAMPLES::
115
+
116
+ sage: x._fricas_().domainOf() # optional - fricas
117
+ Variable(x)
118
+
119
+ sage: (x^2)._fricas_().domainOf() # optional - fricas
120
+ Expression(Integer...)
121
+
122
+ sage: (2*x)._fricas_().integrate(x) # optional - fricas
123
+ 2
124
+ x
125
+ """
126
+ return repr(ex)
127
+
128
+ def derivative(self, ex, operator):
129
+ """
130
+ Convert the derivative of ``self`` in FriCAS.
131
+
132
+ INPUT:
133
+
134
+ - ``ex`` -- a symbolic expression
135
+
136
+ - ``operator`` -- operator
137
+
138
+ Note that ``ex.operator() == operator``.
139
+
140
+ EXAMPLES::
141
+
142
+ sage: var('x,y,z')
143
+ (x, y, z)
144
+ sage: f = function("F")
145
+ sage: f(x)._fricas_() # optional - fricas
146
+ F(x)
147
+ sage: diff(f(x,y,z), x, z, x)._fricas_() # optional - fricas
148
+ F (x,y,z)
149
+ ,1,1,3
150
+
151
+ Check that :issue:`25838` is fixed::
152
+
153
+ sage: var('x')
154
+ x
155
+ sage: F = function('F')
156
+ sage: integrate(F(x), x, algorithm='fricas') # optional - fricas
157
+ integral(F(x), x)
158
+
159
+ sage: integrate(diff(F(x), x)*sin(F(x)), x, algorithm='fricas') # optional - fricas
160
+ -cos(F(x))
161
+
162
+ Check that :issue:`27310` is fixed::
163
+
164
+ sage: f = function("F")
165
+ sage: var("y")
166
+ y
167
+ sage: ex = (diff(f(x,y), x, x, y)).subs(y=x+y); ex
168
+ D[0, 0, 1](F)(x, x + y)
169
+ sage: fricas(ex) # optional - fricas
170
+ F (x,y + x)
171
+ ,1,1,2
172
+ """
173
+ args = ex.operands() # the arguments the derivative is evaluated at
174
+ params = operator.parameter_set()
175
+ params_set = set(params)
176
+ mult = ",".join(str(params.count(i)) for i in params_set)
177
+ if (not all(isinstance(v, Expression) and v.is_symbol() for v in args) or
178
+ len(args) != len(set(args))):
179
+ # An evaluated derivative of the form f'(1) is not a
180
+ # symbolic variable, yet we would like to treat it like
181
+ # one. So, we replace the argument `1` with a temporary
182
+ # variable e.g. `_symbol0` and then evaluate the
183
+ # derivative f'(_symbol0) symbolically at _symbol0=1. See
184
+ # trac #12796. Note that we cannot use SR.temp_var here
185
+ # since two conversions of the same expression have to be
186
+ # equal.
187
+ temp_args = [SR.symbol("_symbol%s" % i) for i in range(len(args))]
188
+ f = operator.function()(*temp_args)
189
+ vars = ",".join(temp_args[i]._fricas_init_() for i in params_set)
190
+ subs = ",".join("%s = %s" % (t._fricas_init_(), a._fricas_init_())
191
+ for t, a in zip(temp_args, args))
192
+ outstr = "eval(D(%s, [%s], [%s]), [%s])" % (f._fricas_init_(), vars, mult, subs)
193
+ else:
194
+ f = operator.function()(*args)
195
+ vars = ",".join(args[i]._fricas_init_() for i in params_set)
196
+ outstr = "D(%s, [%s], [%s])" % (f._fricas_init_(), vars, mult)
197
+
198
+ return outstr
199
+
200
+
201
+ fricas_converter = FriCASConverter()