passagemath-standard-no-symbolics 10.6.31rc3__cp314-cp314-macosx_13_0_arm64.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.
Potentially problematic release.
This version of passagemath-standard-no-symbolics might be problematic. Click here for more details.
- passagemath_standard_no_symbolics-10.6.31rc3.data/scripts/sage-grep +5 -0
- passagemath_standard_no_symbolics-10.6.31rc3.data/scripts/sage-grepdoc +5 -0
- passagemath_standard_no_symbolics-10.6.31rc3.data/scripts/sage-list-packages +103 -0
- passagemath_standard_no_symbolics-10.6.31rc3.dist-info/METADATA +151 -0
- passagemath_standard_no_symbolics-10.6.31rc3.dist-info/RECORD +82 -0
- passagemath_standard_no_symbolics-10.6.31rc3.dist-info/WHEEL +6 -0
- passagemath_standard_no_symbolics-10.6.31rc3.dist-info/top_level.txt +1 -0
- sage/all.py +207 -0
- sage/all_cmdline.py +36 -0
- sage/cli/__init__.py +61 -0
- sage/cli/__main__.py +5 -0
- sage/cli/eval_cmd.py +45 -0
- sage/cli/eval_cmd_test.py +25 -0
- sage/cli/interactive_shell_cmd.py +28 -0
- sage/cli/notebook_cmd.py +51 -0
- sage/cli/notebook_cmd_test.py +39 -0
- sage/cli/options.py +26 -0
- sage/cli/run_file_cmd.py +50 -0
- sage/cli/version_cmd.py +26 -0
- sage/databases/all.py +83 -0
- sage/databases/cubic_hecke_db.py +1527 -0
- sage/dynamics/all.py +31 -0
- sage/dynamics/surface_dynamics_deprecation.py +32 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/mwrank/PRIMES +1 -0
- sage/ext_data/nbconvert/postprocess.py +48 -0
- sage/ext_data/nbconvert/rst_sage.tpl +99 -0
- sage/ext_data/nodoctest +0 -0
- sage/ext_data/notebook-ipython/kernel.json.in +11 -0
- sage/ext_data/notebook-ipython/logo-64x64.png +0 -0
- sage/ext_data/notebook-ipython/logo.svg +352 -0
- sage/ext_data/valgrind/pyalloc.supp +58 -0
- sage/ext_data/valgrind/sage-additional.supp +417 -0
- sage/ext_data/valgrind/sage.supp +43 -0
- sage/ext_data/valgrind/valgrind-python.supp +480 -0
- sage/geometry/all.py +12 -0
- sage/groups/matrix_gps/pickling_overrides.py +110 -0
- sage/homology/tests.py +66 -0
- sage/interacts/algebra.py +20 -0
- sage/interacts/all.py +25 -0
- sage/interacts/calculus.py +24 -0
- sage/interacts/fractals.py +18 -0
- sage/interacts/geometry.py +19 -0
- sage/interacts/library.py +1950 -0
- sage/interacts/library_cython.cpython-314-darwin.so +0 -0
- sage/interacts/statistics.py +19 -0
- sage/interfaces/axiom.py +1002 -0
- sage/interfaces/kash.py +834 -0
- sage/interfaces/lie.py +950 -0
- sage/interfaces/matlab.py +413 -0
- sage/interfaces/mupad.py +686 -0
- sage/interfaces/octave.py +858 -0
- sage/interfaces/phc.py +943 -0
- sage/interfaces/psage.py +189 -0
- sage/interfaces/qsieve.py +4 -0
- sage/interfaces/r.py +2096 -0
- sage/interfaces/read_data.py +46 -0
- sage/interfaces/scilab.py +576 -0
- sage/interfaces/tests.py +81 -0
- sage/libs/all.py +11 -0
- sage/libs/cremona/__init__.py +0 -0
- sage/libs/mwrank/__init__.py +0 -0
- sage/logic/all.py +3 -0
- sage/logic/booleval.py +160 -0
- sage/logic/boolformula.py +1490 -0
- sage/logic/logic.py +856 -0
- sage/logic/logicparser.py +696 -0
- sage/logic/logictable.py +272 -0
- sage/logic/propcalc.py +311 -0
- sage/misc/all.py +28 -0
- sage/misc/lazy_attribute.pyi +11 -0
- sage/rings/all.py +48 -0
- sage/rings/commutative_algebra.py +38 -0
- sage/rings/finite_rings/all.py +21 -0
- sage/rings/numbers_abc.py +58 -0
- sage/rings/polynomial/all.py +22 -0
- sage/rings/polynomial/convolution.py +421 -0
- sage/symbolic/all__sagemath_standard_no_symbolics.py +0 -0
|
@@ -0,0 +1,858 @@
|
|
|
1
|
+
r"""
|
|
2
|
+
Interface to GNU Octave
|
|
3
|
+
|
|
4
|
+
GNU Octave is a free software (GPL) MATLAB-like program with numerical
|
|
5
|
+
routines for integrating, solving systems of equations, special
|
|
6
|
+
functions, and solving (numerically) differential equations. Please see
|
|
7
|
+
http://octave.org/ for more details.
|
|
8
|
+
|
|
9
|
+
The commands in this section only work if you have the optional
|
|
10
|
+
"octave" interpreter installed and available in your PATH. It's not
|
|
11
|
+
necessary to install any special Sage packages.
|
|
12
|
+
|
|
13
|
+
EXAMPLES::
|
|
14
|
+
|
|
15
|
+
sage: octave.eval('2+2') # optional - octave
|
|
16
|
+
'ans = 4'
|
|
17
|
+
|
|
18
|
+
sage: a = octave(10) # optional - octave
|
|
19
|
+
sage: a**10 # optional - octave
|
|
20
|
+
1e+10
|
|
21
|
+
|
|
22
|
+
LOG: - creation (William Stein) - ? (David Joyner, 2005-12-18) -
|
|
23
|
+
Examples (David Joyner, 2005-01-03)
|
|
24
|
+
|
|
25
|
+
Computation of Special Functions
|
|
26
|
+
--------------------------------
|
|
27
|
+
|
|
28
|
+
Octave implements computation of the following special functions
|
|
29
|
+
(see the maxima and gp interfaces for even more special
|
|
30
|
+
functions)::
|
|
31
|
+
|
|
32
|
+
airy
|
|
33
|
+
Airy functions of the first and second kind, and their derivatives.
|
|
34
|
+
airy(0,x) = Ai(x), airy(1,x) = Ai'(x), airy(2,x) = Bi(x), airy(3,x) = Bi'(x)
|
|
35
|
+
besselj
|
|
36
|
+
Bessel functions of the first kind.
|
|
37
|
+
bessely
|
|
38
|
+
Bessel functions of the second kind.
|
|
39
|
+
besseli
|
|
40
|
+
Modified Bessel functions of the first kind.
|
|
41
|
+
besselk
|
|
42
|
+
Modified Bessel functions of the second kind.
|
|
43
|
+
besselh
|
|
44
|
+
Compute Hankel functions of the first (k = 1) or second (k = 2) kind.
|
|
45
|
+
beta
|
|
46
|
+
The Beta function,
|
|
47
|
+
beta (a, b) = gamma (a) * gamma (b) / gamma (a + b).
|
|
48
|
+
betainc
|
|
49
|
+
The incomplete Beta function,
|
|
50
|
+
erf
|
|
51
|
+
The error function,
|
|
52
|
+
erfinv
|
|
53
|
+
The inverse of the error function.
|
|
54
|
+
gamma
|
|
55
|
+
The Gamma function,
|
|
56
|
+
gammainc
|
|
57
|
+
The incomplete gamma function,
|
|
58
|
+
|
|
59
|
+
For example,
|
|
60
|
+
|
|
61
|
+
::
|
|
62
|
+
|
|
63
|
+
sage: # optional - octave
|
|
64
|
+
sage: octave("airy(3,2)")
|
|
65
|
+
4.10068
|
|
66
|
+
sage: octave("beta(2,2)")
|
|
67
|
+
0.166667
|
|
68
|
+
sage: octave("betainc(0.2,2,2)")
|
|
69
|
+
0.104
|
|
70
|
+
sage: octave("besselh(0,2)")
|
|
71
|
+
(0.223891,0.510376)
|
|
72
|
+
sage: octave("besselh(0,1)")
|
|
73
|
+
(0.765198,0.088257)
|
|
74
|
+
sage: octave("besseli(1,2)")
|
|
75
|
+
1.59064
|
|
76
|
+
sage: octave("besselj(1,2)")
|
|
77
|
+
0.576725
|
|
78
|
+
sage: octave("besselk(1,2)")
|
|
79
|
+
0.139866
|
|
80
|
+
sage: octave("erf(0)")
|
|
81
|
+
0
|
|
82
|
+
sage: octave("erf(1)")
|
|
83
|
+
0.842701
|
|
84
|
+
sage: octave("erfinv(0.842)")
|
|
85
|
+
0.998315
|
|
86
|
+
sage: octave("gamma(1.5)")
|
|
87
|
+
0.886227
|
|
88
|
+
sage: octave("gammainc(1.5,1)")
|
|
89
|
+
0.77687
|
|
90
|
+
|
|
91
|
+
Tutorial
|
|
92
|
+
--------
|
|
93
|
+
|
|
94
|
+
EXAMPLES::
|
|
95
|
+
|
|
96
|
+
sage: # optional - octave
|
|
97
|
+
sage: octave('4+10')
|
|
98
|
+
14
|
|
99
|
+
sage: octave('date')
|
|
100
|
+
18-Oct-2007
|
|
101
|
+
sage: octave('5*10 + 6')
|
|
102
|
+
56
|
|
103
|
+
sage: octave('(6+6)/3')
|
|
104
|
+
4
|
|
105
|
+
sage: octave('9')^2
|
|
106
|
+
81
|
|
107
|
+
sage: a = octave(10); b = octave(20); c = octave(30)
|
|
108
|
+
sage: avg = (a+b+c)/3
|
|
109
|
+
sage: avg
|
|
110
|
+
20
|
|
111
|
+
sage: parent(avg)
|
|
112
|
+
Octave
|
|
113
|
+
|
|
114
|
+
::
|
|
115
|
+
|
|
116
|
+
sage: # optional - octave
|
|
117
|
+
sage: my_scalar = octave('3.1415')
|
|
118
|
+
sage: my_scalar
|
|
119
|
+
3.1415
|
|
120
|
+
sage: my_vector1 = octave('[1,5,7]')
|
|
121
|
+
sage: my_vector1
|
|
122
|
+
1 5 7
|
|
123
|
+
sage: my_vector2 = octave('[1;5;7]')
|
|
124
|
+
sage: my_vector2
|
|
125
|
+
1
|
|
126
|
+
5
|
|
127
|
+
7
|
|
128
|
+
sage: my_vector1 * my_vector2
|
|
129
|
+
75
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
# ****************************************************************************
|
|
133
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
|
134
|
+
#
|
|
135
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
136
|
+
#
|
|
137
|
+
# This code is distributed in the hope that it will be useful,
|
|
138
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
139
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
140
|
+
# General Public License for more details.
|
|
141
|
+
#
|
|
142
|
+
# The full text of the GPL is available at:
|
|
143
|
+
#
|
|
144
|
+
# https://www.gnu.org/licenses/
|
|
145
|
+
# ****************************************************************************
|
|
146
|
+
|
|
147
|
+
import os
|
|
148
|
+
from .expect import Expect, ExpectElement
|
|
149
|
+
import pexpect
|
|
150
|
+
from sage.misc.verbose import verbose
|
|
151
|
+
from sage.misc.instancedoc import instancedoc
|
|
152
|
+
from sage.misc.temporary_file import tmp_filename
|
|
153
|
+
from sage.cpython.string import bytes_to_str
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class Octave(Expect):
|
|
157
|
+
r"""
|
|
158
|
+
Interface to the Octave interpreter.
|
|
159
|
+
|
|
160
|
+
EXAMPLES::
|
|
161
|
+
|
|
162
|
+
sage: octave.eval("a = [ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]").strip() # optional - octave
|
|
163
|
+
'a =\n\n 1 1 2\n 3 5 8\n 13 21 33'
|
|
164
|
+
sage: octave.eval("b = [ 1; 3; 13]").strip() # optional - octave
|
|
165
|
+
'b =\n\n 1\n 3\n 13'
|
|
166
|
+
|
|
167
|
+
The following solves the linear equation: a*c = b::
|
|
168
|
+
|
|
169
|
+
sage: octave.eval(r"c=a \ b").strip() # optional - octave # abs tol 0.01
|
|
170
|
+
'c =\n\n 1\n -0\n 0'
|
|
171
|
+
sage: octave.eval("c").strip() # optional - octave # abs tol 0.01
|
|
172
|
+
'c =\n\n 1\n -0\n 0'
|
|
173
|
+
|
|
174
|
+
TESTS:
|
|
175
|
+
|
|
176
|
+
We check that the interface can handle large inputs (see :issue:`940`)::
|
|
177
|
+
|
|
178
|
+
sage: t = '"{}"'.format(10^10000)
|
|
179
|
+
sage: a = octave(t) # optional - octave
|
|
180
|
+
sage: str(a) == ' {}'.format(10^10000) # optional - octave
|
|
181
|
+
True
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
def __init__(self, maxread=None, script_subdirectory=None, logfile=None,
|
|
185
|
+
server=None, server_tmpdir=None, seed=None, command=None):
|
|
186
|
+
"""
|
|
187
|
+
EXAMPLES::
|
|
188
|
+
|
|
189
|
+
sage: octave == loads(dumps(octave))
|
|
190
|
+
True
|
|
191
|
+
"""
|
|
192
|
+
if command is None:
|
|
193
|
+
command = os.getenv('SAGE_OCTAVE_COMMAND') or 'octave-cli'
|
|
194
|
+
if server is None:
|
|
195
|
+
server = os.getenv('SAGE_OCTAVE_SERVER') or None
|
|
196
|
+
# Use a temporary workspace file.
|
|
197
|
+
workspace_file = tmp_filename()
|
|
198
|
+
Expect.__init__(self,
|
|
199
|
+
name='octave',
|
|
200
|
+
# We want the prompt sequence to be unique to avoid confusion with syntax error messages containing >>>
|
|
201
|
+
prompt=r'octave\:\d+> ',
|
|
202
|
+
# We don't want any pagination of output
|
|
203
|
+
command=command + f" --no-line-editing --silent --eval 'PS2(PS1());more off; octave_core_file_name (\"{workspace_file}\")' --persist",
|
|
204
|
+
maxread=maxread,
|
|
205
|
+
server=server,
|
|
206
|
+
server_tmpdir=server_tmpdir,
|
|
207
|
+
script_subdirectory=script_subdirectory,
|
|
208
|
+
restart_on_ctrlc=False,
|
|
209
|
+
verbose_start=False,
|
|
210
|
+
logfile=logfile,
|
|
211
|
+
eval_using_file_cutoff=100)
|
|
212
|
+
self._seed = seed
|
|
213
|
+
|
|
214
|
+
def set_seed(self, seed=None):
|
|
215
|
+
"""
|
|
216
|
+
Set the seed for the random number generator
|
|
217
|
+
for this octave interpreter.
|
|
218
|
+
|
|
219
|
+
EXAMPLES::
|
|
220
|
+
|
|
221
|
+
sage: o = Octave() # optional - octave
|
|
222
|
+
sage: o.set_seed(1) # optional - octave
|
|
223
|
+
1
|
|
224
|
+
sage: [o.rand() for i in range(5)] # optional - octave
|
|
225
|
+
[ 0.134364, 0.847434, 0.763775, 0.255069, 0.495435]
|
|
226
|
+
"""
|
|
227
|
+
if seed is None:
|
|
228
|
+
seed = self.rand_seed()
|
|
229
|
+
self.eval("rand('state',%d)" % seed)
|
|
230
|
+
self._seed = seed
|
|
231
|
+
return seed
|
|
232
|
+
|
|
233
|
+
def __reduce__(self):
|
|
234
|
+
"""
|
|
235
|
+
EXAMPLES::
|
|
236
|
+
|
|
237
|
+
sage: Octave().__reduce__()
|
|
238
|
+
(<function reduce_load_Octave at 0x...>, ())
|
|
239
|
+
"""
|
|
240
|
+
return reduce_load_Octave, tuple([])
|
|
241
|
+
|
|
242
|
+
def _read_in_file_command(self, filename):
|
|
243
|
+
"""
|
|
244
|
+
EXAMPLES::
|
|
245
|
+
|
|
246
|
+
sage: filename = tmp_filename()
|
|
247
|
+
sage: octave._read_in_file_command(filename)
|
|
248
|
+
'source("...");'
|
|
249
|
+
"""
|
|
250
|
+
return 'source("%s");' % filename
|
|
251
|
+
|
|
252
|
+
def _quit_string(self):
|
|
253
|
+
"""
|
|
254
|
+
EXAMPLES::
|
|
255
|
+
|
|
256
|
+
sage: octave._quit_string()
|
|
257
|
+
'quit;'
|
|
258
|
+
"""
|
|
259
|
+
return 'quit;'
|
|
260
|
+
|
|
261
|
+
def _install_hints(self):
|
|
262
|
+
"""
|
|
263
|
+
Return hints on how to install Octave.
|
|
264
|
+
|
|
265
|
+
EXAMPLES::
|
|
266
|
+
|
|
267
|
+
sage: print(octave._install_hints())
|
|
268
|
+
You must get ...
|
|
269
|
+
"""
|
|
270
|
+
return """
|
|
271
|
+
You must get the program "octave" in order to use Octave
|
|
272
|
+
from Sage. You can read all about Octave at
|
|
273
|
+
https://www.gnu.org/software/octave/
|
|
274
|
+
|
|
275
|
+
LINUX:
|
|
276
|
+
Do apt-get install octave as root on your machine (Ubuntu/Debian).
|
|
277
|
+
Other Linux systems have octave too.
|
|
278
|
+
|
|
279
|
+
OS X:
|
|
280
|
+
* This website has details on OS X builds of Octave:
|
|
281
|
+
http://wiki.octave.org/Octave_for_MacOS_X
|
|
282
|
+
* Darwin ports and fink have Octave as well.
|
|
283
|
+
"""
|
|
284
|
+
|
|
285
|
+
def _eval_line(self, line, reformat=True, allow_use_file=False,
|
|
286
|
+
wait_for_prompt=True, restart_if_needed=False):
|
|
287
|
+
"""
|
|
288
|
+
EXAMPLES::
|
|
289
|
+
|
|
290
|
+
sage: print(octave._eval_line('2+2')) #optional - octave
|
|
291
|
+
ans = 4
|
|
292
|
+
"""
|
|
293
|
+
from pexpect.exceptions import EOF
|
|
294
|
+
if not wait_for_prompt:
|
|
295
|
+
return Expect._eval_line(self, line)
|
|
296
|
+
if line == '':
|
|
297
|
+
return ''
|
|
298
|
+
if self._expect is None:
|
|
299
|
+
self._start()
|
|
300
|
+
if allow_use_file and len(line) > 3000:
|
|
301
|
+
return self._eval_line_using_file(line)
|
|
302
|
+
try:
|
|
303
|
+
E = self._expect
|
|
304
|
+
# debug
|
|
305
|
+
# self._synchronize(cmd='1+%s\n')
|
|
306
|
+
verbose("in = '%s'" % line, level=3)
|
|
307
|
+
E.sendline(line)
|
|
308
|
+
E.expect(self._prompt)
|
|
309
|
+
out = bytes_to_str(E.before)
|
|
310
|
+
# debug
|
|
311
|
+
verbose("out = '%s'" % out, level=3)
|
|
312
|
+
except EOF:
|
|
313
|
+
if self._quit_string() in line:
|
|
314
|
+
return ''
|
|
315
|
+
except KeyboardInterrupt:
|
|
316
|
+
self._keyboard_interrupt()
|
|
317
|
+
try:
|
|
318
|
+
if reformat:
|
|
319
|
+
if 'syntax error' in out:
|
|
320
|
+
raise SyntaxError(out)
|
|
321
|
+
out = "\n".join(out.splitlines()[1:])
|
|
322
|
+
return out
|
|
323
|
+
except NameError:
|
|
324
|
+
return ''
|
|
325
|
+
|
|
326
|
+
def _keyboard_interrupt(self):
|
|
327
|
+
print("CntrlC: Interrupting %s..." % self)
|
|
328
|
+
if self._restart_on_ctrlc:
|
|
329
|
+
try:
|
|
330
|
+
self._expect.close(force=1)
|
|
331
|
+
except pexpect.ExceptionPexpect as msg:
|
|
332
|
+
raise RuntimeError("THIS IS A BUG -- PLEASE REPORT. This should never happen.\n" + msg)
|
|
333
|
+
self._start()
|
|
334
|
+
raise KeyboardInterrupt("Restarting %s (WARNING: all variables defined in previous session are now invalid)" % self)
|
|
335
|
+
else:
|
|
336
|
+
self._expect.send('\003') # control-c
|
|
337
|
+
raise KeyboardInterrupt("Ctrl-c pressed while running %s" % self)
|
|
338
|
+
|
|
339
|
+
def quit(self, verbose=False):
|
|
340
|
+
"""
|
|
341
|
+
EXAMPLES::
|
|
342
|
+
|
|
343
|
+
sage: o = Octave()
|
|
344
|
+
sage: o._start() # optional - octave
|
|
345
|
+
sage: o.quit(True) # optional - octave
|
|
346
|
+
Exiting spawned Octave process.
|
|
347
|
+
"""
|
|
348
|
+
# Don't bother, since it just hangs in some cases, and it
|
|
349
|
+
# isn't necessary, since octave behaves well with respect
|
|
350
|
+
# to signals.
|
|
351
|
+
if self._expect is not None:
|
|
352
|
+
if verbose:
|
|
353
|
+
print("Exiting spawned %s process." % self)
|
|
354
|
+
|
|
355
|
+
def _start(self):
|
|
356
|
+
"""
|
|
357
|
+
Start the Octave process.
|
|
358
|
+
|
|
359
|
+
EXAMPLES::
|
|
360
|
+
|
|
361
|
+
sage: # optional - octave
|
|
362
|
+
sage: o = Octave()
|
|
363
|
+
sage: o.is_running()
|
|
364
|
+
False
|
|
365
|
+
sage: o._start()
|
|
366
|
+
sage: o.is_running()
|
|
367
|
+
True
|
|
368
|
+
"""
|
|
369
|
+
Expect._start(self)
|
|
370
|
+
self.eval("page_screen_output=0;")
|
|
371
|
+
self.eval("format none;")
|
|
372
|
+
# set random seed
|
|
373
|
+
self.set_seed(self._seed)
|
|
374
|
+
|
|
375
|
+
def _equality_symbol(self):
|
|
376
|
+
"""
|
|
377
|
+
EXAMPLES::
|
|
378
|
+
|
|
379
|
+
sage: octave('0 == 1') # optional - octave
|
|
380
|
+
0
|
|
381
|
+
sage: octave('1 == 1') # optional - octave
|
|
382
|
+
1
|
|
383
|
+
"""
|
|
384
|
+
return '=='
|
|
385
|
+
|
|
386
|
+
def _true_symbol(self):
|
|
387
|
+
"""
|
|
388
|
+
EXAMPLES::
|
|
389
|
+
|
|
390
|
+
sage: octave('1 == 1') # optional - octave
|
|
391
|
+
1
|
|
392
|
+
"""
|
|
393
|
+
return '1'
|
|
394
|
+
|
|
395
|
+
def _false_symbol(self):
|
|
396
|
+
"""
|
|
397
|
+
EXAMPLES::
|
|
398
|
+
|
|
399
|
+
sage: octave('0 == 1') # optional - octave
|
|
400
|
+
0
|
|
401
|
+
"""
|
|
402
|
+
return '0'
|
|
403
|
+
|
|
404
|
+
def set(self, var, value):
|
|
405
|
+
"""
|
|
406
|
+
Set the variable ``var`` to the given ``value``.
|
|
407
|
+
|
|
408
|
+
EXAMPLES::
|
|
409
|
+
|
|
410
|
+
sage: octave.set('x', '2') # optional - octave
|
|
411
|
+
sage: octave.get('x') # optional - octave
|
|
412
|
+
' 2'
|
|
413
|
+
"""
|
|
414
|
+
cmd = '%s=%s;' % (var, value)
|
|
415
|
+
out = self.eval(cmd)
|
|
416
|
+
if out.find("error") != -1 or out.find("Error") != -1:
|
|
417
|
+
raise TypeError("Error executing code in Octave\nCODE:\n\t%s\nOctave ERROR:\n\t%s" % (cmd, out))
|
|
418
|
+
|
|
419
|
+
def get(self, var):
|
|
420
|
+
"""
|
|
421
|
+
Get the value of the variable ``var``.
|
|
422
|
+
|
|
423
|
+
EXAMPLES::
|
|
424
|
+
|
|
425
|
+
sage: octave.set('x', '2') # optional - octave
|
|
426
|
+
sage: octave.get('x') # optional - octave
|
|
427
|
+
' 2'
|
|
428
|
+
"""
|
|
429
|
+
s = self.eval('%s' % var)
|
|
430
|
+
i = s.find('=')
|
|
431
|
+
return s[i+1:]
|
|
432
|
+
|
|
433
|
+
def clear(self, var):
|
|
434
|
+
"""
|
|
435
|
+
Clear the variable named var.
|
|
436
|
+
|
|
437
|
+
EXAMPLES::
|
|
438
|
+
|
|
439
|
+
sage: octave.set('x', '2') # optional - octave
|
|
440
|
+
sage: octave.clear('x') # optional - octave
|
|
441
|
+
sage: octave.get('x') # optional - octave
|
|
442
|
+
"error: 'x' undefined near line ... column 1"
|
|
443
|
+
"""
|
|
444
|
+
self.eval('clear %s' % var)
|
|
445
|
+
|
|
446
|
+
def console(self):
|
|
447
|
+
"""
|
|
448
|
+
Spawn a new Octave command-line session.
|
|
449
|
+
|
|
450
|
+
This requires that the optional octave program be installed and in
|
|
451
|
+
your PATH, but no optional Sage packages need be installed.
|
|
452
|
+
|
|
453
|
+
EXAMPLES::
|
|
454
|
+
|
|
455
|
+
sage: octave_console() # not tested
|
|
456
|
+
GNU Octave, version 2.1.73 (i386-apple-darwin8.5.3).
|
|
457
|
+
Copyright (C) 2006 John W. Eaton.
|
|
458
|
+
...
|
|
459
|
+
octave:1> 2+3
|
|
460
|
+
ans = 5
|
|
461
|
+
octave:2> [ctl-d]
|
|
462
|
+
|
|
463
|
+
Pressing ctrl-d exits the octave console and returns you to Sage.
|
|
464
|
+
octave, like Sage, remembers its history from one session to
|
|
465
|
+
another.
|
|
466
|
+
"""
|
|
467
|
+
octave_console()
|
|
468
|
+
|
|
469
|
+
def version(self):
|
|
470
|
+
r"""
|
|
471
|
+
Return the version of Octave.
|
|
472
|
+
|
|
473
|
+
OUTPUT: string
|
|
474
|
+
|
|
475
|
+
EXAMPLES::
|
|
476
|
+
|
|
477
|
+
sage: v = octave.version() # optional - octave
|
|
478
|
+
sage: v # optional - octave; random
|
|
479
|
+
'2.13.7'
|
|
480
|
+
|
|
481
|
+
sage: import re
|
|
482
|
+
sage: assert re.match(r"\d+\.\d+\.\d+", v) is not None # optional - octave
|
|
483
|
+
"""
|
|
484
|
+
return str(self("version")).strip()
|
|
485
|
+
|
|
486
|
+
def solve_linear_system(self, A, b):
|
|
487
|
+
r"""
|
|
488
|
+
Use Octave to compute a solution x to ``A*x = b``, as a list.
|
|
489
|
+
|
|
490
|
+
INPUT:
|
|
491
|
+
|
|
492
|
+
- ``A`` -- mxn matrix A with entries in `\QQ` or `\RR`
|
|
493
|
+
|
|
494
|
+
- ``b`` -- m-vector b entries in `\QQ` or `\RR` (resp)
|
|
495
|
+
|
|
496
|
+
OUTPUT: list x (if it exists) which solves ``M*x = b``
|
|
497
|
+
|
|
498
|
+
EXAMPLES::
|
|
499
|
+
|
|
500
|
+
sage: M33 = MatrixSpace(QQ,3,3)
|
|
501
|
+
sage: A = M33([1,2,3,4,5,6,7,8,0])
|
|
502
|
+
sage: V3 = VectorSpace(QQ,3)
|
|
503
|
+
sage: b = V3([1,2,3])
|
|
504
|
+
sage: octave.solve_linear_system(A,b) # optional - octave (and output is slightly random in low order bits)
|
|
505
|
+
[-0.33333299999999999, 0.66666700000000001, -3.5236600000000002e-18]
|
|
506
|
+
|
|
507
|
+
AUTHORS:
|
|
508
|
+
|
|
509
|
+
- David Joyner and William Stein
|
|
510
|
+
"""
|
|
511
|
+
m = A.nrows()
|
|
512
|
+
if m != len(b):
|
|
513
|
+
raise ValueError("dimensions of A and b must be compatible")
|
|
514
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
515
|
+
from sage.rings.rational_field import QQ
|
|
516
|
+
MS = MatrixSpace(QQ, m, 1)
|
|
517
|
+
b = MS(list(b)) # converted b to a "column vector"
|
|
518
|
+
sA = self.sage2octave_matrix_string(A)
|
|
519
|
+
sb = self.sage2octave_matrix_string(b)
|
|
520
|
+
self.eval("a = " + sA)
|
|
521
|
+
self.eval("b = " + sb)
|
|
522
|
+
soln = octave.eval(r"c = a \ b")
|
|
523
|
+
soln = soln.replace("\n\n ", "[")
|
|
524
|
+
soln = soln.rstrip() + "]"
|
|
525
|
+
soln = soln.replace("\n", ",")
|
|
526
|
+
sol = soln[3:]
|
|
527
|
+
return eval(sol)
|
|
528
|
+
|
|
529
|
+
def sage2octave_matrix_string(self, A):
|
|
530
|
+
"""
|
|
531
|
+
Return an octave matrix from a Sage matrix.
|
|
532
|
+
|
|
533
|
+
INPUT:
|
|
534
|
+
|
|
535
|
+
- ``A`` - Sage matrix with entries in the rationals or reals
|
|
536
|
+
|
|
537
|
+
OUTPUT: string that evaluates to an Octave matrix
|
|
538
|
+
|
|
539
|
+
EXAMPLES::
|
|
540
|
+
|
|
541
|
+
sage: M33 = MatrixSpace(QQ,3,3)
|
|
542
|
+
sage: A = M33([1,2,3,4,5,6,7,8,0])
|
|
543
|
+
sage: octave.sage2octave_matrix_string(A) # optional - octave
|
|
544
|
+
'[1, 2, 3; 4, 5, 6; 7, 8, 0]'
|
|
545
|
+
|
|
546
|
+
AUTHORS:
|
|
547
|
+
|
|
548
|
+
- David Joyner and William Stein
|
|
549
|
+
"""
|
|
550
|
+
return str(A.rows()).replace('), (', '; ').replace('(', '').replace(')', '')
|
|
551
|
+
|
|
552
|
+
def de_system_plot(self, f, ics, trange):
|
|
553
|
+
r"""
|
|
554
|
+
Plot (using octave's interface to gnuplot) the solution to a
|
|
555
|
+
`2\times 2` system of differential equations.
|
|
556
|
+
|
|
557
|
+
INPUT:
|
|
558
|
+
|
|
559
|
+
- ``f`` -- a pair of strings representing the
|
|
560
|
+
differential equations; the independent variable must be called x
|
|
561
|
+
and the dependent variable must be called y
|
|
562
|
+
|
|
563
|
+
- ``ics`` -- a pair [x0,y0] such that x(t0) = x0, y(t0) = y0
|
|
564
|
+
|
|
565
|
+
- ``trange`` -- a pair [t0,t1]
|
|
566
|
+
|
|
567
|
+
OUTPUT: a gnuplot window appears
|
|
568
|
+
|
|
569
|
+
EXAMPLES::
|
|
570
|
+
|
|
571
|
+
sage: octave.de_system_plot(['x+y','x-y'], [1,-1], [0,2]) # not tested -- does this actually work (on OS X it fails for me -- William Stein, 2007-10)
|
|
572
|
+
|
|
573
|
+
This should yield the two plots `(t,x(t)), (t,y(t))` on the
|
|
574
|
+
same graph (the `t`-axis is the horizontal axis) of the
|
|
575
|
+
system of ODEs
|
|
576
|
+
|
|
577
|
+
.. MATH::
|
|
578
|
+
|
|
579
|
+
x' = x+y, x(0) = 1;\qquad y' = x-y, y(0) = -1, \quad\text{for}\quad 0 < t < 2.
|
|
580
|
+
"""
|
|
581
|
+
eqn1 = f[0].replace('x', 'x(1)').replace('y', 'x(2)')
|
|
582
|
+
eqn2 = f[1].replace('x', 'x(1)').replace('y', 'x(2)')
|
|
583
|
+
fcn = "function xdot = f(x,t) xdot(1) = %s; xdot(2) = %s; endfunction" % (eqn1, eqn2)
|
|
584
|
+
self.eval(fcn)
|
|
585
|
+
x0_eqn = "x0 = [%s; %s]" % (ics[0], ics[1])
|
|
586
|
+
self.eval(x0_eqn)
|
|
587
|
+
t_eqn = "t = linspace(%s, %s, 200)'" % (trange[0], trange[1])
|
|
588
|
+
self.eval(t_eqn)
|
|
589
|
+
x_eqn = 'x = lsode("f",x0,t);'
|
|
590
|
+
self.eval(x_eqn)
|
|
591
|
+
self.eval("plot(t,x)")
|
|
592
|
+
|
|
593
|
+
def _object_class(self):
|
|
594
|
+
"""
|
|
595
|
+
EXAMPLES::
|
|
596
|
+
|
|
597
|
+
sage: octave._object_class()
|
|
598
|
+
<class 'sage.interfaces.octave.OctaveElement'>
|
|
599
|
+
"""
|
|
600
|
+
return OctaveElement
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
octave_functions = set()
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
def to_complex(octave_string, R):
|
|
607
|
+
r"""
|
|
608
|
+
Helper function to convert octave complex number.
|
|
609
|
+
|
|
610
|
+
TESTS::
|
|
611
|
+
|
|
612
|
+
sage: from sage.interfaces.octave import to_complex
|
|
613
|
+
sage: to_complex('(0,1)', CDF)
|
|
614
|
+
1.0*I
|
|
615
|
+
sage: to_complex('(1.3231,-0.2)', CDF)
|
|
616
|
+
1.3231 - 0.2*I
|
|
617
|
+
"""
|
|
618
|
+
real, imag = octave_string.strip('() ').split(',')
|
|
619
|
+
return R(float(real), float(imag))
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
@instancedoc
|
|
623
|
+
class OctaveElement(ExpectElement):
|
|
624
|
+
def _get_sage_ring(self):
|
|
625
|
+
r"""
|
|
626
|
+
TESTS::
|
|
627
|
+
|
|
628
|
+
sage: octave('1')._get_sage_ring() # optional - octave
|
|
629
|
+
Real Double Field
|
|
630
|
+
sage: octave('I')._get_sage_ring() # optional - octave
|
|
631
|
+
Complex Double Field
|
|
632
|
+
sage: octave('[]')._get_sage_ring() # optional - octave
|
|
633
|
+
Real Double Field
|
|
634
|
+
"""
|
|
635
|
+
if self.isinteger():
|
|
636
|
+
import sage.rings.integer_ring
|
|
637
|
+
return sage.rings.integer_ring.ZZ
|
|
638
|
+
elif self.isreal():
|
|
639
|
+
import sage.rings.real_double
|
|
640
|
+
return sage.rings.real_double.RDF
|
|
641
|
+
elif self.iscomplex():
|
|
642
|
+
import sage.rings.complex_double
|
|
643
|
+
return sage.rings.complex_double.CDF
|
|
644
|
+
else:
|
|
645
|
+
raise TypeError("no Sage ring associated to this element.")
|
|
646
|
+
|
|
647
|
+
def __bool__(self):
|
|
648
|
+
r"""
|
|
649
|
+
Test whether this element is nonzero.
|
|
650
|
+
|
|
651
|
+
EXAMPLES::
|
|
652
|
+
|
|
653
|
+
sage: # optional - octave
|
|
654
|
+
sage: bool(octave('0'))
|
|
655
|
+
False
|
|
656
|
+
sage: bool(octave('[]'))
|
|
657
|
+
False
|
|
658
|
+
sage: bool(octave('[0,0]'))
|
|
659
|
+
False
|
|
660
|
+
sage: bool(octave('[0,0,0;0,0,0]'))
|
|
661
|
+
False
|
|
662
|
+
|
|
663
|
+
sage: bool(octave('0.1')) # optional - octave
|
|
664
|
+
True
|
|
665
|
+
sage: bool(octave('[0,1,0]')) # optional - octave
|
|
666
|
+
True
|
|
667
|
+
sage: bool(octave('[0,0,-0.1;0,0,0]')) # optional - octave
|
|
668
|
+
True
|
|
669
|
+
"""
|
|
670
|
+
return str(self) != ' [](0x0)' and any(x != '0' for x in str(self).split())
|
|
671
|
+
|
|
672
|
+
def _matrix_(self, R=None):
|
|
673
|
+
r"""
|
|
674
|
+
Return Sage matrix from this octave element.
|
|
675
|
+
|
|
676
|
+
EXAMPLES::
|
|
677
|
+
|
|
678
|
+
sage: A = octave('[1,2;3,4.5]') # optional - octave
|
|
679
|
+
sage: matrix(A) # optional - octave
|
|
680
|
+
[1.0 2.0]
|
|
681
|
+
[3.0 4.5]
|
|
682
|
+
sage: _.base_ring() # optional - octave
|
|
683
|
+
Real Double Field
|
|
684
|
+
|
|
685
|
+
sage: A = octave('[I,1;-1,0]') # optional - octave
|
|
686
|
+
sage: matrix(A) # optional - octave
|
|
687
|
+
[1.0*I 1.0]
|
|
688
|
+
[ -1.0 0.0]
|
|
689
|
+
sage: _.base_ring() # optional - octave
|
|
690
|
+
Complex Double Field
|
|
691
|
+
|
|
692
|
+
sage: # optional - octave
|
|
693
|
+
sage: A = octave('[1,2;3,4]')
|
|
694
|
+
sage: matrix(ZZ, A)
|
|
695
|
+
[1 2]
|
|
696
|
+
[3 4]
|
|
697
|
+
sage: A = octave('[1,2;3,4.5]')
|
|
698
|
+
sage: matrix(RR, A)
|
|
699
|
+
[1.00000000000000 2.00000000000000]
|
|
700
|
+
[3.00000000000000 4.50000000000000]
|
|
701
|
+
"""
|
|
702
|
+
if not self.ismatrix():
|
|
703
|
+
raise TypeError('not an octave matrix')
|
|
704
|
+
if R is None:
|
|
705
|
+
R = self._get_sage_ring()
|
|
706
|
+
|
|
707
|
+
s = str(self).strip('\n ')
|
|
708
|
+
w = [u.strip().split(' ') for u in s.split('\n')]
|
|
709
|
+
nrows = len(w)
|
|
710
|
+
ncols = len(w[0])
|
|
711
|
+
|
|
712
|
+
if self.iscomplex():
|
|
713
|
+
w = [[to_complex(x, R) for x in row] for row in w]
|
|
714
|
+
|
|
715
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
716
|
+
return MatrixSpace(R, nrows, ncols)(w)
|
|
717
|
+
|
|
718
|
+
def _vector_(self, R=None):
|
|
719
|
+
r"""
|
|
720
|
+
Return Sage vector from this octave element.
|
|
721
|
+
|
|
722
|
+
EXAMPLES::
|
|
723
|
+
|
|
724
|
+
sage: # optional - octave
|
|
725
|
+
sage: A = octave('[1,2,3,4]')
|
|
726
|
+
sage: vector(ZZ, A)
|
|
727
|
+
(1, 2, 3, 4)
|
|
728
|
+
sage: A = octave('[1,2.3,4.5]')
|
|
729
|
+
sage: vector(A)
|
|
730
|
+
(1.0, 2.3, 4.5)
|
|
731
|
+
sage: A = octave('[1,I]')
|
|
732
|
+
sage: vector(A)
|
|
733
|
+
(1.0, 1.0*I)
|
|
734
|
+
"""
|
|
735
|
+
from sage.modules.free_module import FreeModule
|
|
736
|
+
if not self.isvector():
|
|
737
|
+
raise TypeError('not an octave vector')
|
|
738
|
+
if R is None:
|
|
739
|
+
R = self._get_sage_ring()
|
|
740
|
+
|
|
741
|
+
s = str(self).strip('\n ')
|
|
742
|
+
w = s.strip().split(' ')
|
|
743
|
+
nrows = len(w)
|
|
744
|
+
|
|
745
|
+
if self.iscomplex():
|
|
746
|
+
w = [to_complex(x, R) for x in w]
|
|
747
|
+
|
|
748
|
+
return FreeModule(R, nrows)(w)
|
|
749
|
+
|
|
750
|
+
def _scalar_(self):
|
|
751
|
+
"""
|
|
752
|
+
Return Sage scalar from this octave element.
|
|
753
|
+
|
|
754
|
+
EXAMPLES::
|
|
755
|
+
|
|
756
|
+
sage: A = octave('2833') # optional - octave
|
|
757
|
+
sage: As = A.sage(); As # optional - octave
|
|
758
|
+
2833.0
|
|
759
|
+
sage: As.parent() # optional - octave
|
|
760
|
+
Real Double Field
|
|
761
|
+
|
|
762
|
+
sage: B = sqrt(A) # optional - octave
|
|
763
|
+
sage: Bs = B.sage(); Bs # optional - octave
|
|
764
|
+
53.2259
|
|
765
|
+
sage: Bs.parent() # optional - octave
|
|
766
|
+
Real Double Field
|
|
767
|
+
|
|
768
|
+
sage: C = sqrt(-A) # optional - octave
|
|
769
|
+
sage: Cs = C.sage(); Cs # optional - octave
|
|
770
|
+
53.2259*I
|
|
771
|
+
sage: Cs.parent() # optional - octave
|
|
772
|
+
Complex Double Field
|
|
773
|
+
"""
|
|
774
|
+
if not self.isscalar():
|
|
775
|
+
raise TypeError("not an octave scalar")
|
|
776
|
+
|
|
777
|
+
R = self._get_sage_ring()
|
|
778
|
+
if self.iscomplex():
|
|
779
|
+
return to_complex(str(self), R)
|
|
780
|
+
else:
|
|
781
|
+
return R(str(self))
|
|
782
|
+
|
|
783
|
+
def _sage_(self):
|
|
784
|
+
"""
|
|
785
|
+
Try to parse the octave object and return a sage object.
|
|
786
|
+
|
|
787
|
+
EXAMPLES::
|
|
788
|
+
|
|
789
|
+
sage: # optional - octave
|
|
790
|
+
sage: A = octave('2833')
|
|
791
|
+
sage: A.sage()
|
|
792
|
+
2833.0
|
|
793
|
+
sage: B = sqrt(A)
|
|
794
|
+
sage: B.sage()
|
|
795
|
+
53.2259
|
|
796
|
+
sage: C = sqrt(-A)
|
|
797
|
+
sage: C.sage()
|
|
798
|
+
53.2259*I
|
|
799
|
+
sage: A = octave('[1,2,3,4]')
|
|
800
|
+
sage: A.sage()
|
|
801
|
+
(1.0, 2.0, 3.0, 4.0)
|
|
802
|
+
sage: A = octave('[1,2.3,4.5]')
|
|
803
|
+
sage: A.sage()
|
|
804
|
+
(1.0, 2.3, 4.5)
|
|
805
|
+
sage: A = octave('[1,2.3+I,4.5]')
|
|
806
|
+
sage: A.sage()
|
|
807
|
+
(1.0, 2.3 + 1.0*I, 4.5)
|
|
808
|
+
"""
|
|
809
|
+
if self.isscalar():
|
|
810
|
+
return self._scalar_()
|
|
811
|
+
elif self.isvector():
|
|
812
|
+
return self._vector_()
|
|
813
|
+
elif self.ismatrix():
|
|
814
|
+
return self._matrix_()
|
|
815
|
+
else:
|
|
816
|
+
raise NotImplementedError('octave type is not recognized')
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
# An instance
|
|
820
|
+
octave = Octave()
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
def reduce_load_Octave():
|
|
824
|
+
"""
|
|
825
|
+
EXAMPLES::
|
|
826
|
+
|
|
827
|
+
sage: from sage.interfaces.octave import reduce_load_Octave
|
|
828
|
+
sage: reduce_load_Octave()
|
|
829
|
+
Octave
|
|
830
|
+
"""
|
|
831
|
+
return octave
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
def octave_console():
|
|
835
|
+
"""
|
|
836
|
+
Spawn a new Octave command-line session.
|
|
837
|
+
|
|
838
|
+
This requires that the optional octave program be installed and in
|
|
839
|
+
your PATH, but no optional Sage packages need be installed.
|
|
840
|
+
|
|
841
|
+
EXAMPLES::
|
|
842
|
+
|
|
843
|
+
sage: octave_console() # not tested
|
|
844
|
+
GNU Octave, version 2.1.73 (i386-apple-darwin8.5.3).
|
|
845
|
+
Copyright (C) 2006 John W. Eaton.
|
|
846
|
+
...
|
|
847
|
+
octave:1> 2+3
|
|
848
|
+
ans = 5
|
|
849
|
+
octave:2> [ctl-d]
|
|
850
|
+
|
|
851
|
+
Pressing ctrl-d exits the octave console and returns you to Sage.
|
|
852
|
+
octave, like Sage, remembers its history from one session to
|
|
853
|
+
another.
|
|
854
|
+
"""
|
|
855
|
+
from sage.repl.rich_output.display_manager import get_display_manager
|
|
856
|
+
if not get_display_manager().is_in_terminal():
|
|
857
|
+
raise RuntimeError('Can use the console only in the terminal. Try %%octave magics instead.')
|
|
858
|
+
os.system('octave-cli')
|