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