Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/interfaces/kash.py
4048 views
1
r"""
2
Interface to KASH
3
4
Sage provides an interface to the KASH computer algebra system,
5
which is a *free* (as in beer!) but *closed source* program for
6
algebraic number theory that shares much common code with Magma. To
7
use KASH, you must install the appropriate optional Sage package by
8
typing something like "sage -i kash3-linux-2005.11.22" or "sage -i
9
kash3_osx-2005.11.22". For a list of optional packages type "sage
10
-optional". If you type one of the above commands, the (about 16MB)
11
package will be downloaded automatically (you don't have to do
12
that).
13
14
It is not enough to just have KASH installed on your computer. Note
15
that the KASH Sage package is currently only available for Linux
16
and OSX. If you need Windows, support contact me
17
([email protected]).
18
19
The KASH interface offers three pieces of functionality:
20
21
22
#. ``kash_console()`` - A function that dumps you into
23
an interactive command-line KASH session. Alternatively,
24
25
type ``!kash`` from the Sage prompt.
26
27
#. ``kash(expr)`` - Creation of a Sage object that
28
wraps a KASH object. This provides a Pythonic interface to KASH.
29
For example, if ``f=kash.new(10)``, then
30
``f.Factors()`` returns the prime factorization of
31
`10` computed using KASH.
32
33
#. ``kash.function_name(args ...)`` - Call the
34
indicated KASH function with the given arguments are return the
35
result as a KASH object.
36
37
#. ``kash.eval(expr)`` - Evaluation of arbitrary KASH
38
expressions, with the result returned as a string.
39
40
41
Issues
42
------
43
44
For some reason hitting Control-C to interrupt a calculation
45
doesn't work correctly. (TODO)
46
47
Tutorial
48
--------
49
50
The examples in this tutorial require that the optional kash
51
package be installed.
52
53
Basics
54
~~~~~~
55
56
Basic arithmetic is straightforward. First, we obtain the result as
57
a string.
58
59
::
60
61
sage: kash.eval('(9 - 7) * (5 + 6)') # optional -- kash
62
'22'
63
64
Next we obtain the result as a new KASH object.
65
66
::
67
68
sage: a = kash('(9 - 7) * (5 + 6)'); a # optional -- kash
69
22
70
sage: a.parent() # optional -- kash
71
Kash
72
73
We can do arithmetic and call functions on KASH objects::
74
75
sage: a*a # optional -- kash
76
484
77
sage: a.Factorial() # optional -- kash
78
1124000727777607680000
79
80
Integrated Help
81
~~~~~~~~~~~~~~~
82
83
Use the ``kash.help(name)`` command to get help about a
84
given command. This returns a list of help for each of the
85
definitions of ``name``. Use ``print
86
kash.help(name)`` to nicely print out all signatures.
87
88
Arithmetic
89
~~~~~~~~~~
90
91
Using the ``kash.new`` command we create Kash objects
92
on which one can do arithmetic.
93
94
::
95
96
sage: a = kash(12345) # optional -- kash
97
sage: b = kash(25) # optional -- kash
98
sage: a/b # optional -- kash
99
2469/5
100
sage: a**b # optional -- kash
101
1937659030411463935651167391656422626577614411586152317674869233464019922771432158872187137603759765625
102
103
Variable assignment
104
~~~~~~~~~~~~~~~~~~~
105
106
Variable assignment using ``kash`` is takes place in
107
Sage.
108
109
::
110
111
sage: a = kash('32233') # optional -- kash
112
sage: a # optional -- kash
113
32233
114
115
In particular, ``a`` is not defined as part of the KASH
116
session itself.
117
118
::
119
120
sage: kash.eval('a') # optional -- kash
121
"Error, the variable 'a' must have a value"
122
123
Use ``a.name()`` to get the name of the KASH variable::
124
125
sage: a.name() # somewhat random and optional - kash
126
'sage0'
127
sage: kash(a.name()) # optional -- kash
128
32233
129
130
Integers and Rationals
131
~~~~~~~~~~~~~~~~~~~~~~
132
133
We illustrate arithmetic with integers and rationals in KASH.
134
135
::
136
137
sage: F = kash.Factorization(4352) # optional -- kash
138
sage: F[1] # optional -- kash
139
<2, 8>
140
sage: F[2] # optional -- kash
141
<17, 1>
142
sage: F # optional -- kash
143
[ <2, 8>, <17, 1> ], extended by:
144
ext1 := 1,
145
ext2 := Unassign
146
147
.. note::
148
149
For some very large numbers KASH's integer factorization seems much
150
faster than PARI's (which is the default in Sage).
151
152
::
153
154
sage: kash.GCD(15,25) # optional -- kash
155
5
156
sage: kash.LCM(15,25) # optional -- kash
157
75
158
sage: kash.Div(25,15) # optional -- kash
159
1
160
sage: kash(17) % kash(5) # optional -- kash
161
2
162
sage: kash.IsPrime(10007) # optional -- kash
163
TRUE
164
sage: kash.IsPrime(2005) # optional -- kash
165
FALSE
166
167
sage: kash.NextPrime(10007) # optional -- kash
168
10009
169
170
Real and Complex Numbers
171
~~~~~~~~~~~~~~~~~~~~~~~~
172
173
::
174
175
sage: kash.Precision() # optional -- kash
176
30
177
sage: kash('R') # optional -- kash
178
Real field of precision 30
179
sage: kash.Precision(40) # optional -- kash
180
40
181
sage: kash('R') # optional -- kash
182
Real field of precision 40
183
sage: z = kash('1 + 2*I') # optional -- kash
184
sage: z # optional -- kash
185
1.000000000000000000000000000000000000000 + 2.000000000000000000000000000000000000000*I
186
sage: z*z # optional -- kash
187
-3.000000000000000000000000000000000000000 + 4.000000000000000000000000000000000000000*I
188
189
sage: kash.Cos('1.24') # optional -- kash
190
0.3247962844387762365776934156973803996992
191
sage: kash('1.24').Cos() # optional -- kash
192
0.3247962844387762365776934156973803996992
193
194
sage: kash.Exp('1.24') # optional -- kash
195
3.455613464762675598057615494121998175400
196
197
sage: kash.Precision(30) # optional -- kash
198
30
199
sage: kash.Log('3+4*I') # optional -- kash
200
1.60943791243410037460075933323 + 0.927295218001612232428512462922*I
201
sage: kash.Log('I') # optional -- kash
202
1.57079632679489661923132169164*I
203
204
sage: kash.Sqrt(4) # optional -- kash
205
2.00000000000000000000000000000
206
sage: kash.Sqrt(2) # optional -- kash
207
1.41421356237309504880168872421
208
209
sage: kash.Floor('9/5') # optional -- kash
210
1
211
sage: kash.Floor('3/5') # optional -- kash
212
0
213
214
sage: x_c = kash('3+I') # optional -- kash
215
sage: x_c.Argument() # optional -- kash
216
0.321750554396642193401404614359
217
sage: x_c.Imaginary() # optional -- kash
218
1.00000000000000000000000000000
219
220
Lists
221
~~~~~
222
223
Note that list appends are completely different in KASH than in
224
Python. Use underscore after the function name for the mutation
225
version.
226
227
::
228
229
sage: v = kash([1,2,3]); v # optional -- kash
230
[ 1, 2, 3 ]
231
sage: v[1] # optional -- kash
232
1
233
sage: v[3] # optional -- kash
234
3
235
sage: v.Append([5]) # optional -- kash
236
[ 1, 2, 3, 5 ]
237
sage: v # optional -- kash
238
[ 1, 2, 3 ]
239
sage: v.Append_([5, 6]) # optional -- kash
240
SUCCESS
241
sage: v # optional -- kash
242
[ 1, 2, 3, 5, 6 ]
243
sage: v.Add(5) # optional -- kash
244
[ 1, 2, 3, 5, 6, 5 ]
245
sage: v # optional -- kash
246
[ 1, 2, 3, 5, 6 ]
247
sage: v.Add_(5) # optional -- kash
248
SUCCESS
249
sage: v # optional -- kash
250
[ 1, 2, 3, 5, 6, 5 ]
251
252
The ``Apply`` command applies a function to each
253
element of a list.
254
255
::
256
sage: L = kash([1,2,3,4]) # optional -- kash
257
sage: L.Apply('i -> 3*i') # optional -- kash
258
[ 3, 6, 9, 12 ]
259
sage: L # optional -- kash
260
[ 1, 2, 3, 4 ]
261
sage: L.Apply('IsEven') # optional -- kash
262
[ FALSE, TRUE, FALSE, TRUE ]
263
sage: L # optional -- kash
264
[ 1, 2, 3, 4 ]
265
266
Ranges
267
~~~~~~
268
269
the following are examples of ranges.
270
271
::
272
273
sage: L = kash('[1..10]') # optional -- kash
274
sage: L # optional -- kash
275
[ 1 .. 10 ]
276
sage: L = kash('[2,4..100]') # optional -- kash
277
sage: L # optional -- kash
278
[ 2, 4 .. 100 ]
279
280
Sequences
281
~~~~~~~~~
282
283
Tuples
284
~~~~~~
285
286
Polynomials
287
~~~~~~~~~~~
288
289
::
290
291
sage: f = kash('X^3 + X + 1') # optional -- kash
292
sage: f + f # optional -- kash
293
2*X^3 + 2*X + 2
294
sage: f * f # optional -- kash
295
X^6 + 2*X^4 + 2*X^3 + X^2 + 2*X + 1
296
sage: f.Evaluate(10) # optional -- kash
297
1011
298
sage: Qx = kash.PolynomialAlgebra('Q') # optional -- kash
299
sage: Qx.gen(1)**5 + kash('7/3') # sage1 below somewhat random; optional -- kash
300
sage1.1^5 + 7/3
301
302
Number Fields
303
~~~~~~~~~~~~~
304
305
We create an equation order.
306
307
::
308
309
sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') # optional -- kash
310
sage: OK = f.EquationOrder() # optional -- kash
311
sage: OK # optional -- kash
312
Equation Order with defining polynomial X^5 + 4*X^4 - 56*X^2 - 16*X + 192 over Z
313
314
::
315
316
sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') # optional -- kash
317
sage: O = f.EquationOrder() # optional -- kash
318
sage: a = O.gen(2) # optional -- kash
319
sage: a # optional -- kash
320
[0, 1, 0, 0, 0]
321
sage: O.Basis() # output somewhat random; optional -- kash
322
[
323
_NG.1,
324
_NG.2,
325
_NG.3,
326
_NG.4,
327
_NG.5
328
]
329
sage: O.Discriminant() # optional -- kash
330
1364202618880
331
sage: O.MaximalOrder() # name sage2 below somewhat random; optional -- kash
332
Maximal Order of sage2
333
334
sage: O = kash.MaximalOrder('X^3 - 77') # optional -- kash
335
sage: I = O.Ideal(5,[2, 1, 0]) # optional -- kash
336
sage: I # name sage14 below random; optional -- kash
337
Ideal of sage14
338
Two element generators:
339
[5, 0, 0]
340
[2, 1, 0]
341
342
sage: F = I.Factorisation() # optional -- kash
343
sage: F # name sage14 random; optional -- kash
344
[
345
<Prime Ideal of sage14
346
Two element generators:
347
[5, 0, 0]
348
[2, 1, 0], 1>
349
]
350
351
Determining whether an ideal is principal.
352
353
::
354
355
sage: I.IsPrincipal() # optional -- kash
356
FALSE, extended by:
357
ext1 := Unassign
358
359
Computation of class groups and unit groups::
360
361
sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') # optional -- kash
362
sage: O = kash.EquationOrder(f) # optional -- kash
363
sage: OK = O.MaximalOrder() # optional -- kash
364
sage: OK.ClassGroup() # name sage32 below random; optional -- kash
365
Abelian Group isomorphic to Z/6
366
Defined on 1 generator
367
Relations:
368
6*sage32.1 = 0, extended by:
369
ext1 := Mapping from: grp^abl: sage32 to ids/ord^num: _AA
370
371
::
372
373
sage: U = OK.UnitGroup() # optional -- kash
374
sage: U # name sage34 below random; optional -- kash
375
Abelian Group isomorphic to Z/2 + Z + Z
376
Defined on 3 generators
377
Relations:
378
2*sage34.1 = 0, extended by:
379
ext1 := Mapping from: grp^abl: sage34 to ord^num: sage30
380
381
sage: kash.Apply('x->%s.ext1(x)'%U.name(), U.Generators().List()) # optional -- kash
382
[ [1, -1, 0, 0, 0], [1, 1, 0, 0, 0], [-1, 0, 0, 0, 0] ]
383
384
Function Fields
385
~~~~~~~~~~~~~~~
386
387
::
388
389
sage: k = kash.FiniteField(25) # optional -- kash
390
sage: kT = k.RationalFunctionField() # optional -- kash
391
sage: kTy = kT.PolynomialAlgebra() # optional -- kash
392
sage: T = kT.gen(1) # optional -- kash
393
sage: y = kTy.gen(1) # optional -- kash
394
sage: f = y**3 + T**4 + 1 # optional -- kash
395
396
Long Input
397
----------
398
399
The KASH interface reads in even very long input (using files) in a
400
robust manner, as long as you are creating a new object.
401
402
.. note::
403
404
Using ``kash.eval`` for long input is much less robust, and is not
405
recommended.
406
407
::
408
409
sage: a = kash(range(10000)) # optional -- kash
410
411
Note that KASH seems to not support string or integer literals with
412
more than 1024 digits, which is why the above example uses a list
413
unlike for the other interfaces.
414
"""
415
416
417
418
#*****************************************************************************
419
# Copyright (C) 2005 William Stein <[email protected]>
420
#
421
# Distributed under the terms of the GNU General Public License (GPL)
422
#
423
# This code is distributed in the hope that it will be useful,
424
# but WITHOUT ANY WARRANTY; without even the implied warranty of
425
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
426
# General Public License for more details.
427
#
428
# The full text of the GPL is available at:
429
#
430
# http://www.gnu.org/licenses/
431
#*****************************************************************************
432
433
from expect import Expect, ExpectElement
434
import os
435
436
class Kash(Expect):
437
r"""
438
Interface to the Kash interpreter.
439
440
AUTHORS:
441
442
- William Stein and David Joyner
443
"""
444
def __init__(self,
445
max_workspace_size=None,
446
maxread=100000,
447
script_subdirectory=None,
448
restart_on_ctrlc = True,
449
logfile=None,
450
server=None,
451
server_tmpdir=None):
452
453
"""
454
INPUT:
455
max_workspace_size -- (default: None)
456
set maximal workspace memory usage to <mem>
457
<mem> stands for byte-wise allocation
458
<mem>k stands for kilobyte-wise allocation
459
<mem>m stands for megabyte-wise allocation
460
"""
461
462
463
cmd = "kash3 -b -c -d "
464
if max_workspace_size != None:
465
cmd += " -a %s"%int(max_workspace)
466
Expect.__init__(self,
467
name = 'kash',
468
prompt = 'kash% ',
469
command = cmd,
470
maxread = maxread,
471
server = server,
472
server_tmpdir = server_tmpdir,
473
script_subdirectory = script_subdirectory,
474
restart_on_ctrlc = True,
475
verbose_start = False,
476
logfile = logfile,
477
eval_using_file_cutoff=100,
478
init_code = ['X:=ZX.1;']
479
)
480
# The above init_code programs around a bug reported by Jack Schmidt
481
482
self.__seq = 0
483
484
def _next_var_name(self):
485
if self.__seq == 0:
486
self.eval('_s_ := [ ];')
487
self.__seq += 1
488
return '_s_[%s]'%self.__seq
489
490
def _read_in_file_command(self,filename):
491
return 'Read("%s");'%filename
492
493
def _eval_line_using_file(self, line):
494
F = open(self._local_tmpfile(), 'w')
495
F.write(line)
496
F.close()
497
tmp_to_use = self._local_tmpfile()
498
if self.is_remote():
499
self._send_tmpfile_to_server()
500
tmp_to_use = self._remote_tmpfile()
501
return self._eval_line(self._read_in_file_command(tmp_to_use),
502
allow_use_file=False)
503
504
# Change the default for KASH, since eval using a file doesn't
505
# work except for setting variables.
506
def _eval_line(self, line, allow_use_file=False, wait_for_prompt=True, restart_if_needed=False):
507
return Expect._eval_line(self, line, allow_use_file=allow_use_file,
508
wait_for_prompt=wait_for_prompt)
509
510
def __reduce__(self):
511
return reduce_load_Kash, tuple([])
512
513
def _quit_string(self):
514
return 'quit;'
515
516
def _start(self):
517
try:
518
Expect._start(self)
519
except RuntimeError:
520
raise RuntimeError, "You must install the optional Kash package to use Kash from Sage."
521
# Turn off the annoying timer.
522
self.eval('Time(false);')
523
524
def _object_class(self):
525
return KashElement
526
527
def eval(self, x, newlines=False, strip=True, **kwds):
528
r"""
529
Send the code in the string s to the Kash interpreter and return
530
the output as a string.
531
532
INPUT:
533
534
535
- ``s`` - string containing Kash code.
536
537
- ``newlines`` - bool (default: True); if False,
538
remove all backslash-newlines inserted by the Kash output
539
formatter.
540
541
- ``strip`` - ignored
542
"""
543
x = str(x)
544
x = x.rstrip()
545
if len(x) == 0 or x[len(x) - 1] != ';':
546
x += ';'
547
s = Expect.eval(self, x, **kwds)
548
i = s.find('\r\n')
549
if i != -1:
550
s = s[i+2:]
551
if newlines:
552
return s
553
else:
554
return s.replace("\\\n","")
555
556
## def help(self, name=None):
557
## """
558
## Return help on KASH commands.
559
560
## EXAMPLES:
561
## sage: X = kash.help('IntegerRing') # needs optional kash package
562
563
## """
564
## if name is None:
565
## print '\nTo use KASH help enter kash.help(s). '
566
## print 'The syntax of the string s is given below.\n'
567
## print self.eval('?')
568
## elif name[0] == '?':
569
## print self.eval(name)
570
## else:
571
## print self.eval('?%s'%name)
572
573
def help(self, name=None):
574
"""
575
Return help on KASH commands.
576
577
Returns help on all commands with a given name. If name is None,
578
return the location of the installed Kash HTML documentation.
579
580
EXAMPLES::
581
582
sage: X = kash.help('IntegerRing') # optional -- kash
583
584
There is one entry in X for each item found in the documentation
585
for this function: If you type ``print X[0]`` you will
586
get help on about the first one, printed nicely to the screen.
587
588
AUTHORS:
589
590
- Sebastion Pauli (2006-02-04): during Sage coding sprint
591
"""
592
if name is None:
593
print '\nTo use KASH help enter kash.help(s). '
594
print 'The syntax of the string s is given below.\n'
595
print self.eval('?')
596
return
597
name = str(name)
598
if name[0] == '?':
599
print self.eval(name)
600
else:
601
print self.eval('?%s'%name)
602
603
#if name is None:
604
# return "The Kash manual is installed in %s/local/lib/kash/html"%os.environ['SAGE_ROOT']
605
#V = self.eval('?%s'%name)
606
#return self._doc(V)
607
608
def _doc(self, V):
609
if V.lstrip()[:11] == 'No matches.':
610
return KashDocumentation([])
611
V = V.split('\n')[1:-1]
612
X = []
613
for C in V:
614
i = C.find('m')
615
j = C.find(':')
616
try:
617
n = int(C[i+1:j])
618
except ValueError:
619
full = C
620
else:
621
full = self.eval('?%s'%n)
622
#sig = C[j+2:]
623
X.append(full)
624
return KashDocumentation(X)
625
626
def help_search(self, name):
627
return self._doc(self.eval('?*%s'%name))
628
629
def set(self, var, value):
630
"""
631
Set the variable var to the given value.
632
"""
633
cmd = '%s:=%s;;'%(var,value)
634
#out = self.eval(cmd)
635
out = self._eval_line(cmd, allow_use_file=True)
636
if out.lower().find('error') != -1:
637
raise TypeError, "Error executing code in Kash\nCODE:\n\t%s\nKash ERROR:\n\t%s"%(cmd, out)
638
639
def get(self, var):
640
"""
641
Get the value of the variable var.
642
"""
643
return self.eval('%s;'%var, newlines=False)
644
645
#def clear(self, var):
646
# """
647
# Clear the variable named var.
648
# """
649
# self.eval('Unbind(%s)'%var)
650
651
def _contains(self, v1, v2):
652
return self.eval('%s in %s'%(v1,v2)) == "true"
653
654
def _assign_symbol(self):
655
return ":="
656
657
def _equality_symbol(self):
658
return "="
659
660
def _true_symbol(self):
661
return "TRUE"
662
663
def _false_symbol(self):
664
return "FALSE"
665
666
def console(self):
667
kash_console()
668
669
def version(self):
670
return kash_version()
671
672
class KashElement(ExpectElement):
673
def __mod__(self, other):
674
self._check_valid()
675
if not isinstance(other, KashElement):
676
other = self.parent()(other)
677
other._check_valid()
678
return self.parent()('%s mod %s'%(self._name,other._name))
679
680
def __len__(self):
681
self._check_valid()
682
return int(self.parent().eval('Length(%s)'%self.name()))
683
684
685
class KashDocumentation(list):
686
def __repr__(self):
687
if len(self) == 0:
688
return "No matches."
689
return '\n'.join(self)
690
691
692
def is_KashElement(x):
693
return isinstance(x, KashElement)
694
695
############
696
697
###########
698
699
kash = Kash()
700
701
def reduce_load_Kash():
702
return kash
703
704
import os
705
def kash_console():
706
os.system("kash3 ")
707
708
def kash_version():
709
return kash.eval('VERSION')
710
711
712
def __doctest_cleanup():
713
import sage.interfaces.quit
714
sage.interfaces.quit.expect_quitall()
715
716