├── .gitignore
├── COPYING
├── meson.build
├── NEWS
├── pyproject.toml
├── src
└── sagemath_giac
│ ├── misc.h
│ ├── context.py
│ ├── meson.build
│ ├── giac.pxd
│ ├── gb.py
│ ├── keywords.pxi
│ └── giac.pyx
├── README.rst
├── tools
└── mkkeywords.py
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by python itself (when e.g. running doctests)
2 | src/sagemath_giac/__pycache__/
3 | tools/__pycache__/
4 |
5 | # Created by pip wheel, as suggested in the README
6 | sagemath_giac-*.whl
7 |
8 | # Created by "python -m build", as suggested in the README
9 | dist/
10 |
11 | # Created by "meson setup build", as suggested in the README
12 | build/
13 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | sagemath-giac - support for using Giac within SageMath
2 | Copyright (C) 2024 The Sage Developers
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see .
16 |
--------------------------------------------------------------------------------
/meson.build:
--------------------------------------------------------------------------------
1 | project('sagemath-giac', 'cpp', 'cython',
2 | default_options: ['warning_level=3', 'cpp_std=c++11'],
3 | meson_version: '>=1.2.0'
4 | )
5 |
6 | ## Python
7 | py_module = import('python')
8 |
9 | # Ask explicitly for 'python' so we get the venv python and
10 | # not the one used to run meson.
11 | py = py_module.find_installation('python', pure: false)
12 | py_dep = py.dependency()
13 |
14 | ## Compilers
15 | cxx = meson.get_compiler('cpp')
16 |
17 | subdir('src/sagemath_giac')
18 |
19 | pytest = py_module.find_installation(modules: ['pytest'], required: false)
20 | if pytest.found()
21 | test('pytest',
22 | pytest,
23 | args: ['-m', 'pytest'],
24 | workdir: meson.current_source_dir(),
25 | timeout: 600)
26 | else
27 | message('pytest not found, skipping tests')
28 | endif
29 |
--------------------------------------------------------------------------------
/NEWS:
--------------------------------------------------------------------------------
1 | sagemath-giac-0.1.3 (2025-05-10)
2 |
3 | * Restore build system support for system installations of SageMath
4 | that don't have a top-level __init__.py.
5 |
6 | sagemath-giac-0.1.2 (2025-05-06)
7 |
8 | * Build system support for --editable SageMath installations.
9 |
10 | sagemath-giac-0.1.1 (2025-02-23)
11 |
12 | * Use the c++11 standard instead of c++17 to build. This fixes
13 | a build failure on macOS (and is correct anyway).
14 |
15 | * Better support for building against sage in a venv.
16 |
17 | sagemath-giac-0.1.0 (2025-02-19)
18 |
19 | * Initial release. With a few tweaks, this is the sage.libs.giac
20 | module that was shipped with SageMath in the past.
21 |
22 | * The doctests have been rewritten in pure python, so they can
23 | be run without "sage -t".
24 |
25 | * __init__.py has been split into gb.py (the groebner_basis
26 | function) and context.py (the local_giacsettings decorator). This
27 | is more for convenience than principle; __init__.py causes issues
28 | when doctesting a meson-python project, and Sage is capable of
29 | abstracting away the name changes.
30 |
31 | * A dependency on gmpy2 has replaced sage.libs.gmp.
32 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "cython",
4 | "cysignals",
5 | "gmpy2",
6 | "meson-python",
7 | "sagemath-standard"
8 | ]
9 | build-backend = "mesonpy"
10 |
11 | [project]
12 | name = "sagemath-giac"
13 | version = "0.1.3"
14 | description = "Support for using Giac within SageMath"
15 | readme = "README.rst"
16 | requires-python = ">=3.9"
17 | keywords = ["mathematics", "algebra", "calculus", "giac", "xcas"]
18 | license = { file = "COPYING" }
19 | classifiers = [
20 | "Development Status :: 5 - Production/Stable",
21 | "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
22 | "Programming Language :: Python :: 3",
23 | "Topic :: Scientific/Engineering :: Mathematics",
24 | "Topic :: Software Development :: Libraries :: Python Modules"
25 | ]
26 |
27 | [external]
28 | # https://peps.python.org/pep-0725
29 | host-requires = [
30 | "pkg:generic/giac",
31 | ]
32 |
33 | [project.urls]
34 | Homepage = "https://github.com/sagemath/sagemath-giac"
35 | Documentation = "https://github.com/sagemath/sagemath-giac/blob/master/README.rst"
36 | Repository = "https://github.com/sagemath/sagemath-giac.git"
37 | Issues = "https://github.com/sagemath/sagemath-giac/issues"
38 | Changelog = "https://github.com/sagemath/sagemath-giac/raw/master/NEWS"
39 |
40 | [tool.pytest.ini_options]
41 | addopts = "--doctest-modules --doctest-glob='*.pyx' --doctest-glob='*.rst'"
42 |
--------------------------------------------------------------------------------
/src/sagemath_giac/misc.h:
--------------------------------------------------------------------------------
1 | #ifndef GIACPYMISC_H
2 | #define GIACPYMISC_H
3 | #include
4 |
5 | #include
6 |
7 | using namespace std;
8 | using namespace giac;
9 |
10 | inline void ressetctrl_c(void){
11 | giac::ctrl_c=false;
12 | }
13 |
14 | inline int testctrl_c(void){
15 | if(giac::ctrl_c){
16 | return 1;}
17 | else{
18 | return 0;
19 | }
20 | }
21 |
22 | int giacgenrichcmp(gen & a, gen & b, int op, const context * context_ptr){
23 | int rep=0;//be careful with undef results
24 | switch ( op )
25 | {
26 | case 0 : //<
27 | if (is_strictly_greater(b,a,context_ptr)) {rep = 1;}
28 | break;
29 | case 1 : //<=
30 | if (is_greater(b,a,context_ptr)) {rep = 1;}
31 | break;
32 | case 2 ://==
33 | if (operator_equal(b,a,context_ptr)) {rep = 1;}
34 | break;
35 | case 3 ://!=
36 | if (!operator_equal(b,a,context_ptr)) {rep = 1;}
37 | break;
38 | case 4 ://>
39 | if (is_strictly_greater(a,b,context_ptr)) {rep = 1;}
40 | break;//>=
41 | case 5 :
42 | if (is_greater(a,b,context_ptr)) {rep = 1;}
43 | break;
44 | default :
45 | rep=0;
46 | };
47 | return rep;
48 | }
49 |
50 | gen giacmul(gen & a, gen & b, const context * context_ptr){
51 | return eval(a*b,context_ptr);
52 | }
53 |
54 | gen giacdiv(gen & a, gen & b, const context * context_ptr){
55 | return eval(a/b,context_ptr);
56 | }
57 |
58 | gen giacmod(gen & a, gen & b, const context * context_ptr){
59 | if(b != 0)
60 | return eval(a * makemod(1,b),context_ptr);
61 | else
62 | return eval(makemod(a,b),context_ptr);
63 | }
64 |
65 | int htmlbrowserhelp(char * s){
66 | if (system_browser_command(s))
67 | { return 0;}
68 | else
69 | {return 1;}
70 | }
71 |
72 | string browser_help(const giac::gen & g, int language){
73 | giac::gen f(g);
74 | string s;
75 | giac::html_help_init("aide_cas",language,true,true);
76 | if (f.type==giac::_SYMB)
77 | f=f._SYMBptr->sommet;
78 | if (f.type==giac::_FUNC)
79 | s=f._FUNCptr->ptr()->s;
80 | giac::html_vtt=giac::html_help(giac::html_mtt,s);
81 | if (!giac::html_vtt.empty()){
82 | return giac::html_vtt.front();
83 | }
84 | else{
85 | return "";
86 | }
87 | }
88 |
89 |
90 | void archivegen( const string filename, const gen & g, const context * context_ptr){
91 | ofstream of(filename.c_str());
92 | giac::archive(of,g,context_ptr);
93 | of.close();
94 | }
95 |
96 | gen unarchivegen( const string filename, const context * context_ptr){
97 | ifstream f(filename.c_str());
98 | gen g=giac::unarchive(f,context_ptr);
99 | f.close();
100 | return g;
101 | }
102 |
103 |
104 | #endif
105 |
106 |
--------------------------------------------------------------------------------
/src/sagemath_giac/context.py:
--------------------------------------------------------------------------------
1 | r"""
2 | Context manager and local wrapper for giacsettings.
3 | """
4 |
5 | from sagemath_giac.giac import giacsettings, libgiac
6 |
7 |
8 | class GiacSettingsDefaultContext:
9 | r"""
10 | Context preserve libgiac settings.
11 | """
12 |
13 | def __enter__(self):
14 | """
15 | EXAMPLES::
16 |
17 | >>> from sagemath_giac.context import GiacSettingsDefaultContext
18 | >>> from sagemath_giac.giac import giacsettings
19 | >>> giacsettings.proba_epsilon = 1e-16
20 | >>> with GiacSettingsDefaultContext(): giacsettings.proba_epsilon = 1e-12
21 | >>> giacsettings.proba_epsilon < 1e-14
22 | True
23 |
24 | """
25 | self.proba_epsilon = giacsettings.proba_epsilon
26 | self.threads = giacsettings.threads
27 | # Change the debug level at the end to not have messages at each modification
28 | self.debuginfolevel = libgiac('debug_infolevel()')
29 |
30 | def __exit__(self, typ, value, tb):
31 | """
32 | EXAMPLES::
33 |
34 | >>> from sagemath_giac.context import GiacSettingsDefaultContext
35 | >>> from sagemath_giac.giac import giacsettings
36 | >>> giacsettings.proba_epsilon = 1e-16
37 | >>> with GiacSettingsDefaultContext(): giacsettings.proba_epsilon = 1e-30
38 | >>> giacsettings.proba_epsilon < 1e-20
39 | False
40 | """
41 | # Restore the debug level first to not have messages at each modification
42 | libgiac('debug_infolevel')(self.debuginfolevel)
43 | # NB: giacsettings.epsilon has a different meaning that giacsettings.proba_epsilon.
44 | giacsettings.proba_epsilon = self.proba_epsilon
45 | giacsettings.threads = self.threads
46 |
47 |
48 | def local_giacsettings(func):
49 | """
50 | Decorator to preserve Giac's proba_epsilon and threads settings.
51 |
52 | EXAMPLES::
53 |
54 | >>> def testf(a, b):
55 | ... giacsettings.proba_epsilon = a/100
56 | ... giacsettings.threads = b+2
57 | ... return (giacsettings.proba_epsilon, giacsettings.threads)
58 |
59 | >>> from sagemath_giac.giac import giacsettings
60 | >>> from sagemath_giac.context import local_giacsettings
61 | >>> gporig, gtorig = (giacsettings.proba_epsilon,giacsettings.threads)
62 | >>> gp, gt = local_giacsettings(testf)(giacsettings.proba_epsilon,giacsettings.threads)
63 | >>> gporig == giacsettings.proba_epsilon
64 | True
65 | >>> gtorig == giacsettings.threads
66 | True
67 | >>> gp>> from sage.all import *
22 | >>> from sagemath_giac.giac import libgiac
23 | >>> x = SR.symbol("x", domain="real")
24 | >>> libgiac.integrate(2*min_symbolic(x,2*x),x).sage()
25 | -1/2*x^2*sgn(x) + 3/2*x^2
26 |
27 | After installing sagemath-giac, Sage will automatically gain the
28 | ability to do these integrals. Of course, you also gain access to the
29 | rest of the Giac library, with easy conversions to and from Sage
30 | objects.
31 |
32 | Previously the contents of sagemath-giac were available (within
33 | SageMath) in the ``sage.libs.giac`` module. In this package, we have
34 | been forced to rename it to ``sagemath_giac`` due to some (hopefully
35 | temporary) limitations of Cython in regard to namespace packages:
36 |
37 | * https://github.com/cython/cython/issues/5237
38 | * https://github.com/cython/cython/issues/5335
39 | * https://github.com/cython/cython/issues/6287
40 |
41 | If we had kept the old name, for example, you would not be able to
42 | install sagemath-giac as a normal user for use with the system
43 | installation of Sage. If sagemath-giac is installed, however, SageMath
44 | will export its contents under the old name to avoid breaking
45 | backwards compatibility. If/when Cython support for namespace packages
46 | materializes, the contents of sagemath-giac can be moved back under
47 | ``sage.libs.giac``.
48 |
49 | Building
50 | ========
51 |
52 | It is possible to build the package directly through meson::
53 |
54 | $ meson setup --prefix=$HOME/.local build
55 | $ meson compile -C build
56 |
57 | The prefix is not used until install-time, but eventually it tells
58 | meson where to install the built files. The location ``$HOME/.local``
59 | is most likely your personal python "user site" directory, where
60 | python looks for packages installed with ``pip install --user``.
61 |
62 | Of course, it is also possible to build a wheel the usual way, using::
63 |
64 | $ python -m pip wheel --no-build-isolation --verbose .
65 |
66 | or::
67 |
68 | $ python -m build --no-isolation --skip-dependency-check .
69 |
70 | Skipping the dependency check is necessary if you installed SageMath
71 | using meson, because ``meson install`` installs only the library and
72 | not the python packaging metadata. It is recommended to skip the
73 | dependency check in any case, opting instead to ensure that SageMath
74 | and all of its dependencies are installed (systemwide or in the active
75 | venv) beforehand. Otherwise there is a risk that the build system will
76 | try to download and isolate a new set of build dependencies, which
77 | involves building all of SageMath again.
78 |
79 | Testing
80 | =======
81 |
82 | A few doctests within the module ensure that everything is working. If
83 | you have built the project using meson and a build directory named
84 | ``build``, you can run the tests with::
85 |
86 | $ PYTHONPATH=src:build/src python -m doctest \
87 | README.rst src/sagemath_giac/*.py* \
88 | 2>/dev/null
89 |
90 | We need to add both ``src`` and ``build/src`` (or whatever directory
91 | you passed to meson as your build directory) to ``PYTHONPATH`` so that
92 | python can find both our python modules and the compiled C extension
93 | module. We have redirected stderr to ``/dev/null`` because, otherwise,
94 | a mountain of debug output is printed to the console. A small amount
95 | is still printed to stdout, but that is most likely a bug in libgiac.
96 |
97 | If you have pytest installed, it can also be used::
98 |
99 | $ PYTHONPATH=src:build/src pytest
100 |
101 | Finally, meson is capable of running pytest on your behalf::
102 |
103 | $ PYTHONPATH=src:build/src meson test -C build
104 |
105 | Installation
106 | ============
107 |
108 | After building/testing, you can install the package either using
109 | meson::
110 |
111 | $ meson install -C build
112 |
113 | or from the wheel that you generated earlier::
114 |
115 | $ pip install $(find ./ -type f -name 'sagemath_giac-*.whl')
116 |
117 |
--------------------------------------------------------------------------------
/src/sagemath_giac/giac.pxd:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # ****************************************************************************
3 | # Copyright (C) 2012, Frederic Han
4 | # 2020, Vincent Delecroix <20100.delecroix@gmail.com>
5 | #
6 | # Distributed under the terms of the GNU General Public License (GPL)
7 | # as published by the Free Software Foundation; either version 2 of
8 | # the License, or (at your option) any later version.
9 | # https://www.gnu.org/licenses/
10 | #*****************************************************************************
11 |
12 | from gmpy2.gmpy2 cimport mpz_t, mpz_set
13 | from libcpp.string cimport string
14 |
15 | cdef extern from "giac/giac.h" namespace "giac":
16 | cdef cppclass context:
17 | context()
18 |
19 | cdef struct ref_mpz_t:
20 | pass
21 | cdef struct ref_real_object:
22 | pass
23 | cdef struct ref_complex:
24 | pass
25 | cdef struct ref_identificateur:
26 | pass
27 | cdef struct ref_symbolic:
28 | pass
29 | cdef struct ref_modulo:
30 | pass
31 | cdef struct ref_algext:
32 | pass
33 | cdef struct giac_float:
34 | pass
35 | cdef cppclass Tref_fraction[T]:
36 | pass
37 | cdef cppclass Tref_tensor[T]:
38 | pass
39 | cdef cppclass vecteur:
40 | vecteur(int)
41 | vecteur()
42 | void push_back(gen &)
43 | int size()
44 | cdef struct ref_vecteur:
45 | pass
46 | cdef struct ref_sparse_poly1:
47 | pass
48 | cdef struct ref_string:
49 | pass
50 | cdef struct ref_gen_user:
51 | pass
52 | cdef struct ref_gen_map:
53 | pass
54 | cdef struct ref_eqwdata:
55 | pass
56 | cdef struct ref_grob:
57 | pass
58 | cdef struct ref_void_pointer:
59 | pass
60 |
61 | cdef cppclass gen:
62 | gen() except +
63 | gen(char *, context *) except +
64 | gen(string , context *) except +
65 | gen(int ) except +
66 | gen(long long ) except +
67 | gen(double ) except +
68 | #gen(ref_mpz_t * ) except +
69 | gen(mpz_t & ) except +
70 | gen(void *ptr,short int subt) except +
71 | gen(gen ) except +
72 | gen (vecteur & v,short int s) except +
73 | gen (ref_vecteur * vptr,short int s) except +
74 |
75 | mpz_t * ref_ZINTptr() except +
76 | gen * ref_MODptr() except +
77 | vecteur * ref_VECTptr() except +
78 |
79 | #
80 | unsigned char type
81 | signed char subtype
82 | # (the meaning of types from dispatch.h)
83 | # // immediate type (without mem allocation) should be < _ZINT
84 | # _INT_= 0, // int val
85 | # _DOUBLE_= 1, // double _DOUBLE_val
86 | # // all type below or equal to _DOUBLE_ must be non pointers
87 | # _ZINT= 2, // mpz_t * _ZINTptr
88 | # _REAL= 3, // mpf_t * _REALptr
89 | # // all type strictly below _CPLX must be real types
90 | # _CPLX= 4, // gen * _CPLXptr
91 | # _POLY= 5, // polynome * _POLYptr
92 | # _IDNT= 6, // identificateur * _IDNTptr
93 | # _VECT= 7, // vecteur * _VECTptr
94 | # _SYMB= 8, // symbolic * _SYMBptr
95 | # _SPOL1= 9, // sparse_poly1 * _SPOL1ptr
96 | # _FRAC= 10, // fraction * _FRACptr
97 | # _EXT= 11, // gen * _EXTptr
98 | # _STRNG= 12, // string * _STRNGptr
99 | # _FUNC= 13, // unary_fonction_ptr * _FUNCptr
100 | # _ROOT= 14, // real_complex_rootof *_ROOTptr
101 | # _MOD= 15, // gen * _MODptr
102 | # _USER= 16, // gen_user * _USERptr
103 | # _MAP=17, // map * _MAPptr
104 | # _EQW=18, // eqwdata * _EQWptr
105 | # _GROB=19, // grob * _GROBptr
106 | # _POINTER_=20, // void * _POINTER_val
107 | # _FLOAT_=21 // immediate, _FLOAT_val
108 |
109 |
110 | # immediate types
111 | int val # immediate int (type _INT_)
112 | double _DOUBLE_val # immediate float (type _DOUBLE_)
113 | giac_float _FLOAT_val
114 |
115 | # pointer types
116 | ref_mpz_t * __ZINTptr # long int (type _ZINT)
117 | ref_real_object * __REALptr # extended double (type _REAL)
118 | ref_complex * __CPLXptr # complex as an gen[2] array (type _CPLX)
119 | ref_identificateur * __IDNTptr # global name identifier (type _IDNT)
120 | ref_symbolic * __SYMBptr # for symbolic objects (type _SYMB)
121 | ref_modulo * __MODptr
122 | ref_algext * __EXTptr # 2 gens for alg. extension (type ext)
123 | # alg ext: 1st gen is a std::vector or a fraction, 2nd gen is
124 | # a/ a std::vector, the minimal monic polynomial (the roots are permutable)
125 | # b/ a real_complex_rootof given by it's min poly and
126 | # c/ another type meaning that the root is expressed in terms
127 | # of another rootof, in this case ext_reduce should be called
128 | # For 2nd order extension, X^2=d is used if d!=1 mod 4
129 | # X is the positive solution
130 | # if d=1 mod 4 the equation is X^2-X=(d-1)/4
131 | Tref_fraction[gen] * __FRACptr # fraction (type _FRAC)
132 | Tref_tensor[gen] * __POLYptr # multidim. sparse polynomials (type poly)
133 | # _VECTosite types (std::vector<>)
134 | ref_vecteur * __VECTptr # vecteur: std::vectors & dense_POLY1 (type _VECT)
135 | ref_sparse_poly1 * __SPOL1ptr # std::vector: sparse 1-d poly (type _SPOL1)
136 | ref_string * __STRNGptr
137 | unsigned _FUNC_ # ref_unary_function_ptr * __FUNCptr;
138 | ref_gen_user * __USERptr
139 | ref_gen_map * __MAPptr
140 | ref_eqwdata * __EQWptr
141 | ref_grob * __GROBptr
142 | ref_void_pointer * __POINTERptr
143 |
144 | #operators
145 | gen operator[](int i) except +
146 | gen operator[](gen & i) except +
147 | gen operator()(gen & i,context * contextptr) except +
148 | gen operator()(gen & i,gen & progname,context * contextptr) except +
149 |
150 | gen operator+(gen & b) except +
151 | gen operator-(gen & b) except +
152 | gen operator*(gen & b) except +
153 | gen operator/(gen & b) except +
154 |
155 |
156 | gen GIAC_rdiv "rdiv"(gen & a,gen & b) except + # rational division
157 | gen GIAC_eval "eval" (gen &,int , context *) except +
158 | gen GIAC_protecteval "protecteval" (gen , int, context *) except +
159 | gen GIAC_pow "pow"(gen & ,gen & , context * ) except +
160 | gen GIAC_neg "operator-"(gen & ) except +
161 | gen GIAC_pos "operator+"(gen & ) except +
162 | gen GIAC_factor "_factor" (gen &, context *) except +
163 | gen GIAC_factors "_factors" (gen &, context *) except +
164 | gen GIAC_normal "normal" (gen &, context *) except +
165 | gen GIAC_gcd "_gcd" (gen & args, context *) except +
166 | gen GIAC_smod "_smod" (gen & args, context * ) except +
167 | gen GIAC_mods "_mods" (gen & args, context * ) except +
168 | gen GIAC_makemod "_makemod" (gen & , context * ) except +
169 | string GIAC_print "print" (gen &, context *) except +
170 | string GIAC_gen2tex "gen2tex" (gen &, context *) except +
171 | ref_vecteur * GIAC_makenewvecteur "makenewvecteur"(gen & a,gen & b) except +
172 | gen GIAC_size "_size"(gen & , context *) except +
173 | gen GIAC_pari_unlock "_pari_unlock"(gen & , context *) except +
174 |
175 | unsigned int GIAC_taille "taille"(gen & , unsigned int) except +
176 | void GIAC_try_parse_i "try_parse_i"(bool , context *) except +
177 |
178 | string GIAC_giac_aide_dir "giac_aide_dir"() except +
179 | string GIAC_set_langage "_set_langage"(int , context *) except +
180 |
181 | gen GIAC_sto "sto" (gen &, gen &, bool, context *) except +
182 |
183 | int GIACctrl_c "ctrl_c"
184 |
185 | #test
186 | gen GIAC_Airy_Ai "_Airy_Ai" (gen &, context *) except +
187 | gen GIAC_ifactor "_ifactor" (gen &, context *) except +
188 |
189 |
190 | cdef extern from "misc.h":
191 | void ressetctrl_c() except +
192 | int testctrl_c() except +
193 | int giacgencmp( gen & , gen & , context *) except +
194 | int giacgenrichcmp( gen & , gen & , int, context *) except +
195 | #NB: we use the following multiplication otherwise some giac errors make python quit:
196 | #l=giac([1,2]); l.transpose()*l
197 | gen GIAC_giacmul "giacmul"( gen & , gen & , context *) except +
198 | gen GIAC_giacdiv "giacdiv"( gen & , gen & , context *) except +
199 | gen GIAC_giacmod "giacmod"( gen & , gen & , context *) except +
200 | #
201 | string browser_help(gen & , int lang) except +
202 |
203 | void GIAC_archive "archivegen"( string , gen & , context *) except +
204 | gen GIAC_unarchive "unarchivegen"( string , context *) except +
205 |
--------------------------------------------------------------------------------
/src/sagemath_giac/gb.py:
--------------------------------------------------------------------------------
1 | """
2 | Wrappers for Giac functions
3 |
4 | We provide a python function to compute and convert to sage a Groebner
5 | basis.
6 |
7 | AUTHORS:
8 |
9 | - Martin Albrecht (2015-07-01): initial version
10 | - Han Frederic (2015-07-01): initial version
11 |
12 | EXAMPLES::
13 |
14 | Compute and verify a Groebner basis::
15 |
16 | >>> from sagemath_giac.gb import groebner_basis as gb_giac
17 | >>> from sage.rings.ideal import Cyclic as CyclicIdeal
18 | >>> from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
19 | >>> from sage.rings.rational_field import QQ
20 | >>> P = PolynomialRing(QQ, 6, 'x')
21 | >>> I = CyclicIdeal(P)
22 | >>> B = gb_giac(I.gens())
23 | >>> B
24 | Polynomial Sequence with 45 Polynomials in 6 Variables
25 | >>> B.is_groebner()
26 | True
27 |
28 | """
29 |
30 | # *****************************************************************************
31 | # Copyright (C) 2013 Frederic Han
32 | #
33 | # This program is free software: you can redistribute it and/or modify
34 | # it under the terms of the GNU General Public License as published by
35 | # the Free Software Foundation, either version 2 of the License, or
36 | # (at your option) any later version.
37 | # https://www.gnu.org/licenses/
38 | # *****************************************************************************
39 |
40 | from sage.structure.proof.all import polynomial as proof_polynomial
41 | from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
42 | from sagemath_giac.context import local_giacsettings
43 | from sagemath_giac.giac import giacsettings, libgiac
44 |
45 |
46 | @local_giacsettings
47 | def groebner_basis(gens, proba_epsilon=None, threads=None, prot=False,
48 | elim_variables=None, *args, **kwds):
49 | r"""
50 | Compute a Groebner Basis of an ideal using ``giacpy_sage``. The result is
51 | automatically converted to sage.
52 |
53 | Supported term orders of the underlying polynomial ring are ``lex``,
54 | ``deglex``, ``degrevlex`` and block orders with 2 ``degrevlex`` blocks.
55 |
56 | INPUT:
57 |
58 | - ``gens`` -- an ideal (or a list) of polynomials over a prime field
59 | of characteristic 0 or `p < 2^31`
60 |
61 | - ``proba_epsilon`` -- (default: ``None``) majoration of the probability
62 | of a wrong answer when probabilistic algorithms are allowed
63 |
64 | * if ``proba_epsilon`` is None, the value of
65 | ``sage.structure.proof.all.polynomial()`` is taken. If it is
66 | false then the global ``giacpy_sage.giacsettings.proba_epsilon`` is
67 | used.
68 |
69 | * if ``proba_epsilon`` is 0, probabilistic algorithms are
70 | disabled.
71 |
72 | - ``threads`` -- (default: ``None``) maximal number of threads allowed
73 | for giac. If ``None``, the global ``giacpy_sage.giacsettings.threads`` is
74 | considered.
75 |
76 | - ``prot`` -- boolean (default: ``False``); if ``True`` print detailed information
77 |
78 | - ``elim_variables`` -- (default: ``None``) a list of variables to eliminate
79 | from the ideal
80 |
81 | * if ``elim_variables`` is None, a Groebner basis with respect to the
82 | term ordering of the parent polynomial ring of the polynomials
83 | ``gens`` is computed.
84 |
85 | * if ``elim_variables`` is a list of variables, a Groebner basis of the
86 | elimination ideal with respect to a ``degrevlex`` term order is
87 | computed, regardless of the term order of the polynomial ring.
88 |
89 | OUTPUT: polynomial sequence of the reduced Groebner basis
90 |
91 | EXAMPLES::
92 |
93 | >>> from sage.arith.misc import previous_prime
94 | >>> from sagemath_giac.gb import groebner_basis as gb_giac
95 | >>> from sage.rings.finite_rings.finite_field_constructor import GF
96 | >>> from sage.rings.ideal import Cyclic as CyclicIdeal
97 | >>> from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
98 | >>> P = PolynomialRing(GF(previous_prime(2**31)), 6, 'x')
99 | >>> I = CyclicIdeal(P)
100 | >>> B = gb_giac(I.gens())
101 | >>> B
102 | Polynomial Sequence with 45 Polynomials in 6 Variables
103 | >>> B.is_groebner()
104 | True
105 |
106 | Elimination ideals can be computed by passing ``elim_variables``::
107 |
108 | >>> from sagemath_giac.gb import groebner_basis as gb_giac
109 | >>> P = PolynomialRing(GF(previous_prime(2**31)), 5, 'x')
110 | >>> I = CyclicIdeal(P)
111 | >>> B = gb_giac(I.gens(), elim_variables=[P.gen(0), P.gen(2)])
112 | >>> B.is_groebner()
113 | True
114 | >>> B.ideal() == I.elimination_ideal([P.gen(0), P.gen(2)])
115 | True
116 |
117 | Computations over QQ can benefit from a probabilistic lifting::
118 |
119 | >>> from sage.rings.rational_field import QQ
120 | >>> from sage.rings.ideal import Ideal
121 | >>> from sage.structure.proof.all import polynomial as proof_polynomial
122 | >>> P = PolynomialRing(QQ, 5, 'x')
123 | >>> I = Ideal([P.random_element(3,7) for j in range(5)])
124 | >>> B1 = gb_giac(I.gens(),1e-16)
125 | >>> proof_polynomial(True)
126 | >>> B2 = gb_giac(I.gens())
127 | >>> B1 == B2
128 | True
129 | >>> B1.is_groebner()
130 | True
131 |
132 | You can get detailed information by setting ``prot=True``, but
133 | it won't appear in the doctest output because C libraries are
134 | missed by python's doctest input/output redirection::
135 |
136 | >>> from sage.rings.ideal import Katsura as KatsuraIdeal
137 | >>> P = PolynomialRing(QQ, 8, 'x')
138 | >>> I = KatsuraIdeal(P)
139 | >>> B = gb_giac(I, prot=True)
140 | >>> B
141 | Polynomial Sequence with 74 Polynomials in 8 Variables
142 |
143 | TESTS::
144 |
145 | >>> from sagemath_giac.giac import libgiac
146 | >>> libgiac("x2:=22; x4:='whywouldyoudothis'")
147 | 22,whywouldyoudothis
148 | >>> gb_giac(I)
149 | Traceback (most recent call last):
150 | ...
151 | ValueError: Variables names ['x2', 'x4'] conflict in giac. Change them or purge them from in giac with libgiac.purge('x2')
152 | >>> libgiac.purge('x2'),libgiac.purge('x4')
153 | (22, whywouldyoudothis)
154 | >>> gb_giac(I)
155 | Polynomial Sequence with 74 Polynomials in 8 Variables
156 |
157 | >>> I = Ideal(P(0),P(0))
158 | >>> I.groebner_basis() == gb_giac(I)
159 | True
160 |
161 | Test the supported term orderings::
162 |
163 | sage: from sage.rings.ideal import Cyclic as CyclicIdeal
164 | sage: P = PolynomialRing(QQ, 'x', 4, order='lex')
165 | sage: B = gb_giac(CyclicIdeal(P))
166 | ...
167 | sage: B.is_groebner(), B.ideal() == CyclicIdeal(P)
168 | (True, True)
169 | sage: P = P.change_ring(order='deglex')
170 | sage: B = gb_giac(CyclicIdeal(P))
171 | ...
172 | sage: B.is_groebner(), B.ideal() == CyclicIdeal(P)
173 | (True, True)
174 | sage: P = P.change_ring(order='degrevlex(2),degrevlex(2)')
175 | sage: B = gb_giac(CyclicIdeal(P))
176 | ...
177 | sage: B.is_groebner(), B.ideal() == CyclicIdeal(P)
178 | (True, True)
179 | """
180 | try:
181 | iter(gens)
182 | except TypeError:
183 | gens = gens.gens()
184 |
185 | # get the ring from gens
186 | P = next(iter(gens)).parent()
187 | K = P.base_ring()
188 | p = K.characteristic()
189 |
190 | # check if the ideal is zero. (giac 1.2.0.19 segfault)
191 | from sage.rings.ideal import Ideal
192 | if (Ideal(gens)).is_zero():
193 | return PolynomialSequence([P(0)], P, immutable=True)
194 |
195 | # check for name confusions
196 | blackgiacconstants = ['i', 'e'] # NB e^k is expanded to exp(k)
197 | blacklist = blackgiacconstants + [str(j) for j in libgiac.VARS()]
198 | problematicnames = sorted(set(P.gens_dict()).intersection(blacklist))
199 |
200 | if problematicnames:
201 | raise ValueError("Variables names %s conflict in giac. Change them or purge them from in giac with libgiac.purge(\'%s\')"
202 | % (problematicnames, problematicnames[0]))
203 |
204 | if K.is_prime_field() and p == 0:
205 | F = libgiac(gens)
206 | elif K.is_prime_field() and p < 2**31:
207 | F = (libgiac(gens) % p)
208 | else:
209 | raise NotImplementedError("Only prime fields of cardinal < 2^31 are implemented in Giac for Groebner bases.")
210 |
211 | # proof or probabilistic reconstruction
212 | if proba_epsilon is None:
213 | if proof_polynomial():
214 | giacsettings.proba_epsilon = 0
215 | else:
216 | giacsettings.proba_epsilon = 1e-15
217 | else:
218 | giacsettings.proba_epsilon = proba_epsilon
219 |
220 | # prot
221 | if prot:
222 | libgiac('debug_infolevel(2)')
223 |
224 | # threads
225 | if threads is not None:
226 | giacsettings.threads = threads
227 |
228 | if elim_variables is None:
229 | var_names = P.variable_names()
230 | order_name = P.term_order().name()
231 | if order_name == "degrevlex":
232 | giac_order = "revlex"
233 | elif order_name == "lex":
234 | giac_order = "plex"
235 | elif order_name == "deglex":
236 | giac_order = "tdeg"
237 | else:
238 | blocks = P.term_order().blocks()
239 | if (len(blocks) == 2 and
240 | all(order.name() == "degrevlex" for order in blocks)):
241 | giac_order = "revlex"
242 | var_names = var_names[:len(blocks[0])]
243 | else:
244 | raise NotImplementedError(
245 | "%s is not a supported term order in "
246 | "Giac Groebner bases." % P.term_order())
247 |
248 | # compute de groebner basis with giac
249 | gb_giac = F.gbasis(list(var_names), giac_order)
250 |
251 | else:
252 | gb_giac = F.eliminate(list(elim_variables), 'gbasis')
253 |
254 | return PolynomialSequence(gb_giac, P, immutable=True)
255 |
--------------------------------------------------------------------------------
/src/sagemath_giac/keywords.pxi:
--------------------------------------------------------------------------------
1 | # file auto generated by mkkeywords.py
2 | blacklist = ['eval', 'cas_setup', 'i', 'list', 'input', 'in', 'sto', 'string', 'and', 'break', 'continue', 'else', 'for', 'from', 'if', 'not', 'or', 'pow', 'print', 'return', 'set[]', 'try', 'while', 'open', 'output', 'do', 'of', 'Request', 'i[]', '[]', 'ffunction', 'sleep', '[..]']
3 |
4 | toremove = ['!', '!=', '#', '$', '%', '/%', '%/', '%{%}', '&&', '&*', '&^', "'", '()', '*', '*=', '+', '-', '+&', '+=', '+infinity', '-<', '-=', '->', '-infinity', '.*', '.+', '.-', './', '.^', '/=', ':=', '<', '<=', '=', '=<', '==', '=>', '>', '>=', '?', '@', '@@', 'ACOSH', 'ACOT', 'ACSC', 'ASEC', 'ASIN', 'ASINH', 'ATAN', 'ATANH', 'COND', 'COS', 'COSH', 'COT', 'CSC', 'CST', 'Celsius2Fahrenheit', 'ClrDraw', 'ClrGraph', 'ClrIO', 'CyclePic', 'DIGITS', 'DOM_COMPLEX', 'DOM_FLOAT', 'DOM_FUNC', 'DOM_IDENT', 'DOM_INT', 'DOM_LIST', 'DOM_RAT', 'DOM_STRING', 'DOM_SYMBOLIC', 'DOM_int', 'DelFold', 'DelVar', 'Det', 'Dialog', 'Digits', 'Disp', 'DispG', 'DispHome', 'DrawFunc', 'DrawInv', 'DrawParm', 'DrawPol', 'DrawSlp', 'DropDown', 'DrwCtour', 'ERROR', 'EXP', 'EndDlog', 'FALSE', 'False', 'Fahrenheit2Celsius', 'Fill', 'Gcd', 'GetFold', 'Graph', 'IFTE', 'Input', 'InputStr', 'Int', 'Inverse', 'LN', 'LQ', 'LSQ', 'NORMALD', 'NewFold', 'NewPic', 'Nullspace', 'Output', 'Ox_2d_unit_vector', 'Ox_3d_unit_vector', 'Oy_2d_unit_vector', 'Oy_3d_unit_vector', 'Oz_3d_unit_vector', 'Pause', 'PopUp', 'Quo', 'REDIM', 'REPLACE', 'RclPic', 'Rem', 'Resultant', 'RplcPic', 'Rref', 'SCALE', 'SCALEADD', 'SCHUR', 'SIN', 'SVD', 'SVL', 'SWAPCOL', 'SWAPROW', 'SetFold', 'Si', 'StoPic', 'Store', 'TAN', 'TRUE', 'True', 'TeX', 'Text', 'Title', 'Unarchiv', 'WAIT', '^', '_(cm/s)', '_(ft/s)', '_(ft*lb)', '_(m/s)', '_(m/s^2)', '_(rad/s)', '_(rad/s^2)', '_(tr/min)', '_(tr/s)', '_A', '_Angstrom', '_Bq', '_Btu', '_Ci', '_F', '_F_', '_Fdy', '_G_', '_Gal', '_Gy', '_H', '_Hz', '_I0_', '_J', '_K', '_Kcal', '_MHz', '_MW', '_MeV', '_N', '_NA_', '_Ohm', '_P', '_PSun_', '_Pa', '_R', '_REarth_', '_RSun_', '_R_', '_Rankine', '_Rinfinity_', '_S', '_St', '_StdP_', '_StdT_', '_Sv', '_T', '_V', '_Vm_', '_W', '_Wb', '_Wh', '_a', '_a0_', '_acre', '_alpha_', '_angl_', '_arcmin', '_arcs', '_atm', '_au', '_b', '_bar', '_bbl', '_bblep', '_bu', '_buUS', '_c3_', '_c_', '_cal', '_cd', '_chain', '_cm', '_cm^2', '_cm^3', '_ct', '_cu', '_d', '_dB', '_deg', '_degreeF', '_dyn', '_eV', '_epsilon0_', '_epsilon0q_', '_epsilonox_', '_epsilonsi_', '_erg', '_f0_', '_fath', '_fbm', '_fc', '_fermi', '_flam', '_fm', '_ft', '_ft*lb', '_ftUS', '_ft^2', '_ft^3', '_g', '_g_', '_ga', '_galC', '_galUK', '_galUS', '_gf', '_gmol', '_gon', '_grad', '_grain', '_h', '_h_', '_ha', '_hbar_', '_hp', '_in', '_inH20', '_inHg', '_in^2', '_in^3', '_j', '_kWh', '_k_', '_kg', '_kip', '_km', '_km^2', '_knot', '_kph', '_kq_', '_l', '_lam', '_lambda0_', '_lambdac_', '_lb', '_lbf', '_lbmol', '_lbt', '_lep', '_liqpt', '_lm', '_lx', '_lyr', '_m', '_mEarth_', '_m^2', '_m^3', '_me_', '_mho', '_miUS', '_miUS^2', '_mi^2', '_mil', '_mile', '_mille', '_ml', '_mm', '_mmHg', '_mn', '_mol', '_mp_', '_mph', '_mpme_', '_mu0_', '_muB_', '_muN_', '_oz', '_ozUK', '_ozfl', '_ozt', '_pc', '_pdl', '_ph', '_phi_', '_pk', '_psi', '_ptUK', '_q_', '_qe_', '_qepsilon0_', '_qme_', '_qt', '_rad', '_rad_', '_rd', '_rem', '_rod', '_rpm', '_s', '_sb', '_sd_', '_sigma_', '_slug', '_sr', '_st', '_syr_', '_t', '_tbsp', '_tec', '_tep', '_tex', '_therm', '_ton', '_tonUK', '_torr', '_tr', '_tsp', '_twopi_', '_u', '_yd', '_yd^2', '_yd^3', '_yr', '_µ', '_µ', 'assert', 'affichage', 'alors', 'animate', 'animate3d', 'animation', 'approx_mode', 'archive', 'args', 'as_function_of', 'asc', 'asec', 'assign', 'backquote', 'begin', 'black', 'blanc', 'bleu', 'bloc', 'blue', 'breakpoint', 'by', 'c1oc2', 'c1op2', 'cache_tortue', 'cap', 'cap_flat_line', 'cap_round_line', 'cap_square_line', 'case', 'cat', 'catch', 'cd', 'choosebox', 'click', 'close', 'complex_mode', 'de', 'del', 'debug', 'default', 'div', 'double', 'ecris', 'efface', 'elif', 'end', 'end_for', 'end_if', 'end_while', 'epaisseur', 'epaisseur_ligne_1', 'epaisseur_ligne_2', 'epaisseur_ligne_3', 'epaisseur_ligne_4', 'epaisseur_ligne_5', 'epaisseur_ligne_6', 'epaisseur_ligne_7', 'epaisseur_point_1', 'epaisseur_point_2', 'epaisseur_point_3', 'epaisseur_point_4', 'epaisseur_point_5', 'epaisseur_point_6', 'epaisseur_point_7', 'erase', 'erase3d', 'est_cocyclique', 'est_inclus', 'et', 'faire', 'faux', 'feuille', 'ffaire', 'ffonction', 'fi', 'filled', 'fin_enregistrement', 'float', 'fonction', 'fopen', 'format', 'fpour', 'frame_3d', 'frames', 'fsi', 'ftantque', 'func', 'function', 'gauche', 'gl_ortho', 'gl_quaternion', 'gl_rotation', 'gl_shownames', 'gl_texture', 'gl_x', 'gl_x_axis_color', 'gl_x_axis_name', 'gl_x_axis_unit', 'gl_xtick', 'gl_y', 'gl_y_axis_color', 'gl_y_axis_name', 'gl_y_axis_unit', 'gl_ytick', 'gl_z', 'gl_z_axis_color', 'gl_z_axis_name', 'gl_z_axis_unit', 'gl_ztick', 'gnuplot', 'goto', 'graph2tex', 'graph3d2tex', 'graphe', 'graphe3d', 'graphe_probabiliste', 'graphe_suite', 'green', 'grid_paper', 'hidden_name', 'identifier', 'ifft', 'ifte', 'inputform', 'intersect', 'is_included', 'jusqu_a', 'jusqua', 'jusque', 'keep_algext', 'kill', 'label', 'labels', 'len', 'leve_crayon', 'line_width_1', 'line_width_2', 'line_width_3', 'line_width_4', 'line_width_5', 'line_width_6', 'line_width_7', 'lis', 'local', 'minus', 'mod', 'noir', 'nom_cache', 'non', 'od', 'option', 'otherwise', 'ou', 'pas', 'point_arret', 'point_carre', 'point_croix', 'point_div', 'point_etoile', 'point_invisible', 'point_losange', 'point_milieu', 'point_plus', 'point_point', 'point_polaire', 'point_triangle', 'point_width_1', 'point_width_2', 'point_width_3', 'point_width_4', 'point_width_5', 'point_width_6', 'point_width_7', 'pour', 'proc', 'program', 'quadrant1', 'quadrant2', 'quadrant3', 'quadrant4', 'range', 'redim', 'repeat', 'repete', 'repeter', 'replace', 'restart', 'rouge', 'saisir', 'saisir_chaine', 'sauve', 'save_history', 'scale', 'scaleadd', 'si', 'sinon', 'size', 'stack', 'step', 'switch', 'tantque', 'test', 'textinput', 'then', 'thiele', 'time', 'to', 'union', 'until', 'var', 'vector', 'vers', 'vert', 'vrai', 'watch', 'when', 'white', 'with_sqrt', 'write', 'wz_certificate', 'xor', 'yellow', '{}', '|', '||', 'expression']
5 |
6 | moremethods = ['type', 'zip']
7 |
8 | mostkeywords = ['Airy_Ai', 'Airy_Bi', 'Archive', 'BesselJ', 'BesselY', 'Beta', 'BlockDiagonal', 'Ci', 'Circle', 'Col', 'CopyVar', 'Dirac', 'Ei', 'Factor', 'GF', 'Gamma', 'Heaviside', 'JordanBlock', 'LU', 'LambertW', 'Li', 'Line', 'LineHorz', 'LineTan', 'LineVert', 'Phi', 'Pi', 'Psi', 'QR', 'RandSeed', 'Row', 'SortA', 'SortD', 'UTPC', 'UTPF', 'UTPN', 'UTPT', 'VARS', 'VAS', 'VAS_positive', 'Zeta', 'a2q', 'abcuv', 'about', 'abs', 'abscissa', 'accumulate_head_tail', 'acos', 'acos2asin', 'acos2atan', 'acosh', 'acot', 'acsc', 'acyclic', 'add', 'add_arc', 'add_edge', 'add_vertex', 'additionally', 'addtable', 'adjacency_matrix', 'adjoint_matrix', 'affix', 'algsubs', 'algvar', 'all_trig_solutions', 'allpairs_distance', 'alog10', 'altitude', 'angle', 'angle_radian', 'angleat', 'angleatraw', 'ans', 'antiprism_graph', 'append', 'apply', 'approx', 'arc', 'arcLen', 'arccos', 'arccosh', 'arclen', 'arcsin', 'arcsinh', 'arctan', 'arctanh', 'area', 'areaat', 'areaatraw', 'areaplot', 'arg', 'array', 'arrivals', 'articulation_points', 'asin', 'asin2acos', 'asin2atan', 'asinh', 'assign_edge_weights', 'assume', 'at', 'atan', 'atan2acos', 'atan2asin', 'atanh', 'atrig2ln', 'augment', 'auto_correlation', 'autosimplify', 'avance', 'avgRC', 'axes', 'axis', 'back', 'backward', 'baisse_crayon', 'bandwidth', 'bar_plot', 'barplot', 'bartlett_hann_window', 'barycenter', 'base', 'basis', 'batons', 'bellman_ford', 'bernoulli', 'besselJ', 'besselY', 'betad', 'betad_cdf', 'betad_icdf', 'betavariate', 'bezier', 'bezout_entiers', 'biconnected_components', 'binomial', 'binomial_cdf', 'binomial_icdf', 'bins', 'bipartite', 'bipartite_matching', 'bisection_solver', 'bisector', 'bit_depth', 'bitand', 'bitor', 'bitxor', 'blackman_harris_window', 'blackman_window', 'blockmatrix', 'bohman_window', 'border', 'boxcar', 'boxwhisker', 'brent_solver', 'bvpsolve', 'cFactor', 'cSolve', 'cZeros', 'camembert', 'canonical_form', 'canonical_labeling', 'cartesian_product', 'cauchy', 'cauchy_cdf', 'cauchy_icdf', 'cauchyd', 'cauchyd_cdf', 'cauchyd_icdf', 'cdf', 'ceil', 'ceiling', 'center', 'center2interval', 'centered_cube', 'centered_tetrahedron', 'cfactor', 'cfsolve', 'changebase', 'channel_data', 'channels', 'char', 'charpoly', 'chinrem', 'chisquare', 'chisquare_cdf', 'chisquare_icdf', 'chisquared', 'chisquared_cdf', 'chisquared_icdf', 'chisquaret', 'choice', 'cholesky', 'chr', 'chrem', 'chromatic_index', 'chromatic_number', 'chromatic_polynomial', 'circle', 'circumcircle', 'classes', 'clear', 'clique_cover', 'clique_cover_number', 'clique_number', 'clique_stats', 'clustering_coefficient', 'coeff', 'coeffs', 'col', 'colDim', 'colNorm', 'colSwap', 'coldim', 'collect', 'colnorm', 'color', 'colspace', 'colswap', 'comDenom', 'comb', 'combine', 'comment', 'common_perpendicular', 'companion', 'compare', 'complete_binary_tree', 'complete_graph', 'complete_kary_tree', 'complex', 'complex_variables', 'complexroot', 'concat', 'cond', 'condensation', 'cone', 'confrac', 'conic', 'conj', 'conjugate_equation', 'conjugate_gradient', 'connected', 'connected_components', 'cont', 'contains', 'content', 'contourplot', 'contract_edge', 'convert', 'convertir', 'convex', 'convexhull', 'convolution', 'coordinates', 'copy', 'correlation', 'cos', 'cos2sintan', 'cosh', 'cosine_window', 'cot', 'cote', 'count', 'count_eq', 'count_inf', 'count_sup', 'courbe_parametrique', 'courbe_polaire', 'covariance', 'covariance_correlation', 'cpartfrac', 'crationalroot', 'crayon', 'createwav', 'cross', 'crossP', 'cross_correlation', 'cross_point', 'cross_ratio', 'crossproduct', 'csc', 'csolve', 'csv2gen', 'cube', 'cumSum', 'cumsum', 'cumulated_frequencies', 'curl', 'current_sheet', 'curvature', 'curve', 'cyan', 'cycle2perm', 'cycle_graph', 'cycleinv', 'cycles2permu', 'cyclotomic', 'cylinder', 'dash_line', 'dashdot_line', 'dashdotdot_line', 'dayofweek', 'deSolve', 'debut_enregistrement', 'degree', 'degree_sequence', 'delcols', 'delete_arc', 'delete_edge', 'delete_vertex', 'delrows', 'deltalist', 'denom', 'densityplot', 'departures', 'derive', 'deriver', 'desolve', 'dessine_tortue', 'det', 'det_minor', 'developper', 'developper_transcendant', 'dfc', 'dfc2f', 'diag', 'diff', 'digraph', 'dijkstra', 'dim', 'directed', 'discard_edge_attribute', 'discard_graph_attribute', 'discard_vertex_attribute', 'disjoint_union', 'display', 'disque', 'disque_centre', 'distance', 'distance2', 'distanceat', 'distanceatraw', 'divergence', 'divide', 'divis', 'division_point', 'divisors', 'divmod', 'divpc', 'dnewton_solver', 'dodecahedron', 'domain', 'dot', 'dotP', 'dot_paper', 'dotprod', 'draw_arc', 'draw_circle', 'draw_graph', 'draw_line', 'draw_pixel', 'draw_polygon', 'draw_rectangle', 'droit', 'droite_tangente', 'dsolve', 'duration', 'e', 'e2r', 'ecart_type', 'ecart_type_population', 'ecm_factor', 'edge_connectivity', 'edges', 'egcd', 'egv', 'egvl', 'eigVc', 'eigVl', 'eigenvals', 'eigenvalues', 'eigenvectors', 'eigenvects', 'element', 'eliminate', 'ellipse', 'entry', 'envelope', 'epsilon', 'epsilon2zero', 'equal', 'equal2diff', 'equal2list', 'equation', 'equilateral_triangle', 'erf', 'erfc', 'error', 'est_permu', 'euler', 'euler_gamma', 'euler_lagrange', 'eval_level', 'evala', 'evalb', 'evalc', 'evalf', 'evalm', 'even', 'evolute', 'exact', 'exbisector', 'excircle', 'execute', 'exp', 'exp2list', 'exp2pow', 'exp2trig', 'expand', 'expexpand', 'expln', 'exponential', 'exponential_cdf', 'exponential_icdf', 'exponential_regression', 'exponential_regression_plot', 'exponentiald', 'exponentiald_cdf', 'exponentiald_icdf', 'export_graph', 'export_mathml', 'expovariate', 'expr', 'extend', 'extract_measure', 'extrema', 'ezgcd', 'f2nd', 'fMax', 'fMin', 'fPart', 'faces', 'facteurs_premiers', 'factor', 'factor_xn', 'factorial', 'factoriser', 'factoriser_entier', 'factoriser_sur_C', 'factors', 'fadeev', 'false', 'falsepos_solver', 'fclose', 'fcoeff', 'fdistrib', 'fft', 'fieldplot', 'find', 'find_cycles', 'findhelp', 'fisher', 'fisher_cdf', 'fisher_icdf', 'fisherd', 'fisherd_cdf', 'fisherd_icdf', 'fitdistr', 'flatten', 'float2rational', 'floor', 'flow_polynomial', 'fmod', 'foldl', 'foldr', 'fonction_derivee', 'forward', 'fourier', 'fourier_an', 'fourier_bn', 'fourier_cn', 'fprint', 'frac', 'fracmod', 'frame_2d', 'frequencies', 'frobenius_norm', 'froot', 'fsolve', 'fullparfrac', 'funcplot', 'function_diff', 'fxnd', 'gammad', 'gammad_cdf', 'gammad_icdf', 'gammavariate', 'gauss', 'gauss15', 'gauss_seidel_linsolve', 'gaussian_window', 'gaussjord', 'gaussquad', 'gbasis', 'gbasis_max_pairs', 'gbasis_reinject', 'gbasis_simult_primes', 'gcd', 'gcdex', 'genpoly', 'geometric', 'geometric_cdf', 'geometric_icdf', 'getDenom', 'getKey', 'getNum', 'getType', 'get_edge_attribute', 'get_edge_weight', 'get_graph_attribute', 'get_vertex_attribute', 'girth', 'gl_showaxes', 'grad', 'gramschmidt', 'graph', 'graph_automorphisms', 'graph_charpoly', 'graph_complement', 'graph_diameter', 'graph_equal', 'graph_join', 'graph_power', 'graph_rank', 'graph_spectrum', 'graph_union', 'graph_vertices', 'greduce', 'greedy_color', 'grid_graph', 'groupermu', 'hadamard', 'half_cone', 'half_line', 'halftan', 'halftan_hyp2exp', 'halt', 'hamdist', 'hamming_window', 'hann_poisson_window', 'hann_window', 'harmonic_conjugate', 'harmonic_division', 'has', 'has_arc', 'has_edge', 'hasard', 'head', 'heading', 'heapify', 'heappop', 'heappush', 'hermite', 'hessenberg', 'hessian', 'heugcd', 'hexagon', 'highlight_edges', 'highlight_subgraph', 'highlight_trail', 'highlight_vertex', 'highpass', 'hilbert', 'histogram', 'hold', 'homogeneize', 'homothety', 'horner', 'hybrid_solver', 'hybridj_solver', 'hybrids_solver', 'hybridsj_solver', 'hyp2exp', 'hyperbola', 'hypercube_graph', 'iPart', 'iabcuv', 'ibasis', 'ibpdv', 'ibpu', 'icdf', 'ichinrem', 'ichrem', 'icomp', 'icontent', 'icosahedron', 'id', 'identity', 'idivis', 'idn', 'iegcd', 'ifactor', 'ifactors', 'ifourier', 'igamma', 'igcd', 'igcdex', 'ihermite', 'ilaplace', 'im', 'imag', 'image', 'implicitdiff', 'implicitplot', 'import_graph', 'inString', 'in_ideal', 'incidence_matrix', 'incident_edges', 'incircle', 'increasing_power', 'independence_number', 'indets', 'index', 'induced_subgraph', 'inequationplot', 'inf', 'infinity', 'insert', 'insmod', 'int', 'intDiv', 'integer', 'integrate', 'integrer', 'inter', 'interactive_odeplot', 'interactive_plotode', 'interp', 'interval', 'interval2center', 'interval_graph', 'inv', 'inverse', 'inversion', 'invisible_point', 'invlaplace', 'invztrans', 'iquo', 'iquorem', 'iratrecon', 'irem', 'isPrime', 'is_acyclic', 'is_arborescence', 'is_biconnected', 'is_bipartite', 'is_clique', 'is_collinear', 'is_concyclic', 'is_conjugate', 'is_connected', 'is_coplanar', 'is_cospherical', 'is_cut_set', 'is_cycle', 'is_directed', 'is_element', 'is_equilateral', 'is_eulerian', 'is_forest', 'is_graphic_sequence', 'is_hamiltonian', 'is_harmonic', 'is_harmonic_circle_bundle', 'is_harmonic_line_bundle', 'is_inside', 'is_integer_graph', 'is_isomorphic', 'is_isosceles', 'is_network', 'is_orthogonal', 'is_parallel', 'is_parallelogram', 'is_permu', 'is_perpendicular', 'is_planar', 'is_prime', 'is_pseudoprime', 'is_rectangle', 'is_regular', 'is_rhombus', 'is_square', 'is_strongly_connected', 'is_strongly_regular', 'is_tournament', 'is_tree', 'is_triconnected', 'is_two_edge_connected', 'is_vertex_colorable', 'is_weighted', 'ismith', 'isobarycenter', 'isom', 'isomorphic_copy', 'isopolygon', 'isosceles_triangle', 'isprime', 'ithprime', 'jacobi_equation', 'jacobi_linsolve', 'jacobi_symbol', 'jordan', 'kde', 'keep_pivot', 'ker', 'kernel', 'kernel_density', 'kneser_graph', 'kolmogorovd', 'kolmogorovt', 'kovacicsols', 'kspaths', 'l1norm', 'l2norm', 'lagrange', 'laguerre', 'laplace', 'laplacian', 'laplacian_matrix', 'latex', 'lcf_graph', 'lcm', 'lcoeff', 'ldegree', 'left', 'left_rectangle', 'legend', 'legendre', 'legendre_symbol', 'length', 'lgcd', 'lhs', 'ligne_chapeau_carre', 'ligne_chapeau_plat', 'ligne_chapeau_rond', 'ligne_polygonale', 'ligne_polygonale_pointee', 'ligne_tiret', 'ligne_tiret_point', 'ligne_tiret_pointpoint', 'ligne_trait_plein', 'limit', 'limite', 'lin', 'line', 'line_graph', 'line_inter', 'line_paper', 'line_segments', 'linear_interpolate', 'linear_regression', 'linear_regression_plot', 'lineariser', 'lineariser_trigo', 'linfnorm', 'linsolve', 'linspace', 'lis_phrase', 'list2exp', 'list2mat', 'list_edge_attributes', 'list_graph_attributes', 'list_vertex_attributes', 'listplot', 'lll', 'ln', 'lname', 'lncollect', 'lnexpand', 'locus', 'log', 'log10', 'logarithmic_regression', 'logarithmic_regression_plot', 'logb', 'logistic_regression', 'logistic_regression_plot', 'lower', 'lowest_common_ancestor', 'lowpass', 'lp_assume', 'lp_bestprojection', 'lp_binary', 'lp_binaryvariables', 'lp_breadthfirst', 'lp_depthfirst', 'lp_depthlimit', 'lp_firstfractional', 'lp_gaptolerance', 'lp_hybrid', 'lp_initialpoint', 'lp_integer', 'lp_integertolerance', 'lp_integervariables', 'lp_interiorpoint', 'lp_iterationlimit', 'lp_lastfractional', 'lp_maxcuts', 'lp_maximize', 'lp_method', 'lp_mostfractional', 'lp_nodelimit', 'lp_nodeselect', 'lp_nonnegative', 'lp_nonnegint', 'lp_pseudocost', 'lp_simplex', 'lp_timelimit', 'lp_variables', 'lp_varselect', 'lp_verbose', 'lpsolve', 'lsmod', 'lsq', 'lu', 'lvar', 'mRow', 'mRowAdd', 'magenta', 'make_directed', 'make_weighted', 'makelist', 'makemat', 'makesuite', 'makevector', 'map', 'maple2mupad', 'maple2xcas', 'maple_ifactors', 'maple_mode', 'markov', 'mat2list', 'mathml', 'matpow', 'matrix', 'matrix_norm', 'max', 'maxflow', 'maximal_independent_set', 'maximize', 'maximum_clique', 'maximum_degree', 'maximum_independent_set', 'maximum_matching', 'maxnorm', 'mean', 'median', 'median_line', 'member', 'mgf', 'mid', 'middle_point', 'midpoint', 'min', 'minimal_edge_coloring', 'minimal_spanning_tree', 'minimal_vertex_coloring', 'minimax', 'minimize', 'minimum_cut', 'minimum_degree', 'mkisom', 'mksa', 'modgcd', 'mods', 'monotonic', 'montre_tortue', 'moustache', 'moving_average', 'moyal', 'moyenne', 'mul', 'mult_c_conjugate', 'mult_conjugate', 'multinomial', 'multiplier_conjugue', 'multiplier_conjugue_complexe', 'multiply', 'mupad2maple', 'mupad2xcas', 'mycielski', 'nCr', 'nDeriv', 'nInt', 'nPr', 'nSolve', 'ncols', 'negbinomial', 'negbinomial_cdf', 'negbinomial_icdf', 'neighbors', 'network_transitivity', 'newList', 'newMat', 'newton', 'newton_solver', 'newtonj_solver', 'nextperm', 'nextprime', 'nlpsolve', 'nodisp', 'non_recursive_normal', 'nop', 'nops', 'norm', 'normal', 'normal_cdf', 'normal_icdf', 'normald', 'normald_cdf', 'normald_icdf', 'normalize', 'normalt', 'normalvariate', 'nprimes', 'nrows', 'nuage_points', 'nullspace', 'number_of_edges', 'number_of_spanning_trees', 'number_of_triangles', 'number_of_vertices', 'numer', 'octahedron', 'odd', 'odd_girth', 'odd_graph', 'odeplot', 'odesolve', 'op', 'open_polygon', 'ord', 'order', 'order_size', 'ordinate', 'orthocenter', 'orthogonal', 'osculating_circle', 'p1oc2', 'p1op2', 'pa2b2', 'pade', 'parabola', 'parallel', 'parallelepiped', 'parallelogram', 'parameq', 'parameter', 'paramplot', 'parfrac', 'pari', 'part', 'partfrac', 'parzen_window', 'pas_de_cote', 'path_graph', 'pcar', 'pcar_hessenberg', 'pcoef', 'pcoeff', 'pencolor', 'pendown', 'penup', 'perimeter', 'perimeterat', 'perimeteratraw', 'periodic', 'perm', 'perminv', 'permu2cycles', 'permu2mat', 'permuorder', 'permute_vertices', 'perpen_bisector', 'perpendicular', 'petersen_graph', 'peval', 'pi', 'pie', 'piecewise', 'pivot', 'pixoff', 'pixon', 'planar', 'plane', 'plane_dual', 'playsnd', 'plex', 'plot', 'plot3d', 'plotarea', 'plotcdf', 'plotcontour', 'plotdensity', 'plotfield', 'plotfunc', 'plotimplicit', 'plotinequation', 'plotlist', 'plotode', 'plotparam', 'plotpolar', 'plotproba', 'plotseq', 'plotspectrum', 'plotwav', 'plus_point', 'pmin', 'point', 'point2d', 'point3d', 'poisson', 'poisson_cdf', 'poisson_icdf', 'poisson_window', 'polar', 'polar_coordinates', 'polar_point', 'polarplot', 'pole', 'poly2symb', 'polyEval', 'polygon', 'polygone_rempli', 'polygonplot', 'polygonscatterplot', 'polyhedron', 'polynom', 'polynomial_regression', 'polynomial_regression_plot', 'position', 'poslbdLMQ', 'posubLMQ', 'potential', 'pow2exp', 'power_regression', 'power_regression_plot', 'powermod', 'powerpc', 'powexpand', 'powmod', 'prepend', 'preval', 'prevperm', 'prevprime', 'primpart', 'printf', 'prism', 'prism_graph', 'product', 'projection', 'proot', 'propFrac', 'propfrac', 'psrgcd', 'ptayl', 'purge', 'pwd', 'pyramid', 'python_compat', 'q2a', 'qr', 'quadric', 'quadrilateral', 'quantile', 'quartile1', 'quartile3', 'quartiles', 'quest', 'quo', 'quorem', 'quote', 'r2e', 'radical_axis', 'radius', 'ramene', 'rand', 'randMat', 'randNorm', 'randPoly', 'randbetad', 'randbinomial', 'randchisquare', 'randexp', 'randfisher', 'randgammad', 'randgeometric', 'randint', 'randmarkov', 'randmatrix', 'randmultinomial', 'randnorm', 'random', 'random_bipartite_graph', 'random_digraph', 'random_graph', 'random_network', 'random_planar_graph', 'random_regular_graph', 'random_sequence_graph', 'random_tournament', 'random_tree', 'random_variable', 'randperm', 'randpoisson', 'randpoly', 'randseed', 'randstudent', 'randvar', 'randvector', 'randweibulld', 'rank', 'ranm', 'ranv', 'rassembler_trigo', 'rat_jordan', 'rational', 'rationalroot', 'ratnormal', 'rdiv', 're', 'read', 'readrgb', 'readwav', 'real', 'realroot', 'reciprocation', 'rect', 'rectangle', 'rectangle_droit', 'rectangle_gauche', 'rectangle_plein', 'rectangular_coordinates', 'recule', 'red', 'reduced_conic', 'reduced_quadric', 'ref', 'reflection', 'regroup', 'relabel_vertices', 'reliability_polynomial', 'rem', 'remain', 'remove', 'reorder', 'resample', 'residue', 'resoudre', 'resoudre_dans_C', 'resoudre_systeme_lineaire', 'resultant', 'reverse', 'reverse_graph', 'reverse_rsolve', 'revert', 'revlex', 'revlist', 'rgb', 'rhombus', 'rhombus_point', 'rhs', 'riemann_window', 'right', 'right_rectangle', 'right_triangle', 'risch', 'rm_a_z', 'rm_all_vars', 'rmbreakpoint', 'rmmod', 'rmwatch', 'romberg', 'rombergm', 'rombergt', 'rond', 'root', 'rootof', 'roots', 'rotate', 'rotation', 'round', 'row', 'rowAdd', 'rowDim', 'rowNorm', 'rowSwap', 'rowdim', 'rownorm', 'rowspace', 'rowswap', 'rref', 'rsolve', 'same', 'sample', 'samplerate', 'sans_factoriser', 'saute', 'scalarProduct', 'scalar_product', 'scatterplot', 'schur', 'sec', 'secant_solver', 'segment', 'seidel_spectrum', 'seidel_switch', 'select', 'semi_augment', 'seq', 'seqplot', 'seqsolve', 'sequence_graph', 'series', 'set_edge_attribute', 'set_edge_weight', 'set_graph_attribute', 'set_pixel', 'set_vertex_attribute', 'set_vertex_positions', 'shift', 'shift_phase', 'shortest_path', 'show_pixels', 'shuffle', 'sierpinski_graph', 'sign', 'signature', 'signe', 'similarity', 'simp2', 'simplex_reduce', 'simplifier', 'simplify', 'simpson', 'simult', 'sin', 'sin2costan', 'sinc', 'sincos', 'single_inter', 'sinh', 'sizes', 'slope', 'slopeat', 'slopeatraw', 'smith', 'smod', 'snedecor', 'snedecor_cdf', 'snedecor_icdf', 'snedecord', 'snedecord_cdf', 'snedecord_icdf', 'solid_line', 'solve', 'somme', 'sommet', 'sort', 'sorta', 'sortd', 'sorted', 'soundsec', 'spanning_tree', 'sphere', 'spline', 'split', 'spring', 'sq', 'sqrfree', 'sqrt', 'square', 'square_point', 'srand', 'sst', 'sst_in', 'st_ordering', 'star_graph', 'star_point', 'stdDev', 'stddev', 'stddevp', 'steffenson_solver', 'stereo2mono', 'str', 'strongly_connected_components', 'student', 'student_cdf', 'student_icdf', 'studentd', 'studentt', 'sturm', 'sturmab', 'sturmseq', 'style', 'subMat', 'subdivide_edges', 'subgraph', 'subs', 'subsop', 'subst', 'substituer', 'subtype', 'sum', 'sum_riemann', 'suppress', 'surd', 'svd', 'swapcol', 'swaprow', 'switch_axes', 'sylvester', 'symb2poly', 'symbol', 'syst2mat', 'tCollect', 'tExpand', 'table', 'tablefunc', 'tableseq', 'tabsign', 'tabvar', 'tail', 'tan', 'tan2cossin2', 'tan2sincos', 'tan2sincos2', 'tangent', 'tangente', 'tanh', 'taux_accroissement', 'taylor', 'tchebyshev1', 'tchebyshev2', 'tcoeff', 'tcollect', 'tdeg', 'tensor_product', 'tetrahedron', 'texpand', 'thickness', 'threshold', 'throw', 'title', 'titre', 'tlin', 'tonnetz', 'topologic_sort', 'topological_sort', 'torus_grid_graph', 'total_degree', 'tourne_droite', 'tourne_gauche', 'tpsolve', 'trace', 'trail', 'trail2edges', 'trames', 'tran', 'transitive_closure', 'translation', 'transpose', 'trapeze', 'trapezoid', 'traveling_salesman', 'tree', 'tree_height', 'tri', 'triangle', 'triangle_paper', 'triangle_plein', 'triangle_point', 'triangle_window', 'trig2exp', 'trigcos', 'trigexpand', 'triginterp', 'trigsimplify', 'trigsin', 'trigtan', 'trn', 'true', 'trunc', 'truncate', 'truncate_graph', 'tsimplify', 'tuer', 'tukey_window', 'tutte_polynomial', 'two_edge_connected_components', 'ufactor', 'ugamma', 'unapply', 'unarchive', 'underlying_graph', 'unfactored', 'uniform', 'uniform_cdf', 'uniform_icdf', 'uniformd', 'uniformd_cdf', 'uniformd_icdf', 'unitV', 'unquote', 'upper', 'user_operator', 'usimplify', 'valuation', 'vandermonde', 'variables_are_files', 'variance', 'version', 'vertex_connectivity', 'vertex_degree', 'vertex_distance', 'vertex_in_degree', 'vertex_out_degree', 'vertices', 'vertices_abc', 'vertices_abca', 'vpotential', 'web_graph', 'weibull', 'weibull_cdf', 'weibull_icdf', 'weibulld', 'weibulld_cdf', 'weibulld_icdf', 'weibullvariate', 'weight_matrix', 'weighted', 'weights', 'welch_window', 'wheel_graph', 'widget_size', 'wilcoxonp', 'wilcoxons', 'wilcoxont', 'writergb', 'writewav', 'xcas_mode', 'xml_print', 'xyztrange', 'zeros', 'ztrans']
9 |
10 |
--------------------------------------------------------------------------------
/tools/mkkeywords.py:
--------------------------------------------------------------------------------
1 | r"""
2 | This file is to help the maintainer to upgrade the giac keywords
3 | in sagemath-giac. It creates files ``auto-methods.pxi``,
4 | ``keywords.pxi``, and ``newkeywords.pxi``. It needs:
5 |
6 | - the ``cas_help`` program from a giac installation
7 | - the ``aide_cas.txt`` file that you can build yourself like this::
8 |
9 | $ grep '^# ' /path/to/giac/docs/aide_cas | cut -d' ' -f2 > aide_cas.txt
10 |
11 | It should not be used on-the-fly (e.g. in an installation script),
12 | because auto-methods.pxi takes quite a long time to build, and because
13 | adding new giac keywords often breaks the interface. Not implementing
14 | a new giac keyword, on the other hand, doesn't not cause any immediate
15 | harm.
16 |
17 | The file ``newkeywords.pxi`` is created to check things manually but
18 | is not used by this interface.
19 |
20 | AUTHORS:
21 |
22 | - Frederic Han (2020-07)
23 |
24 | """
25 | from subprocess import PIPE, Popen
26 |
27 | blacklist = ['eval', 'cas_setup', 'i', 'list', 'input', 'in', 'sto', 'string', 'and', 'break', 'continue', 'else', 'for', 'from', 'if', 'not', 'or', 'pow', 'print', 'return', 'set[]', 'try', 'while', 'open', 'output', 'do', 'of', 'Request', 'i[]', '[]', 'ffunction', 'sleep', '[..]']
28 |
29 | toremove = ['!', '!=', '#', '$', '%', '/%', '%/', '%{%}', '&&', '&*', '&^', "'", '()', '*', '*=', '+', '-', '+&', '+=', '+infinity', '-<', '-=', '->', '-infinity', '.*', '.+', '.-', './', '.^', '/=', ':=', '<', '<=', '=', '=<', '==', '=>', '>', '>=', '?', '@', '@@', 'ACOSH', 'ACOT', 'ACSC', 'ASEC', 'ASIN', 'ASINH', 'ATAN', 'ATANH', 'COND', 'COS', 'COSH', 'COT', 'CSC', 'CST', 'Celsius2Fahrenheit', 'ClrDraw', 'ClrGraph', 'ClrIO', 'CyclePic', 'DIGITS', 'DOM_COMPLEX', 'DOM_FLOAT', 'DOM_FUNC', 'DOM_IDENT', 'DOM_INT', 'DOM_LIST', 'DOM_RAT', 'DOM_STRING', 'DOM_SYMBOLIC', 'DOM_int', 'DelFold', 'DelVar', 'Det', 'Dialog', 'Digits', 'Disp', 'DispG', 'DispHome', 'DrawFunc', 'DrawInv', 'DrawParm', 'DrawPol', 'DrawSlp', 'DropDown', 'DrwCtour', 'ERROR', 'EXP', 'EndDlog', 'FALSE', 'False', 'Fahrenheit2Celsius', 'Fill', 'Gcd', 'GetFold', 'Graph', 'IFTE', 'Input', 'InputStr', 'Int', 'Inverse', 'LN', 'LQ', 'LSQ', 'NORMALD', 'NewFold', 'NewPic', 'Nullspace', 'Output', 'Ox_2d_unit_vector', 'Ox_3d_unit_vector', 'Oy_2d_unit_vector', 'Oy_3d_unit_vector', 'Oz_3d_unit_vector', 'Pause', 'PopUp', 'Quo', 'REDIM', 'REPLACE', 'RclPic', 'Rem', 'Resultant', 'RplcPic', 'Rref', 'SCALE', 'SCALEADD', 'SCHUR', 'SIN', 'SVD', 'SVL', 'SWAPCOL', 'SWAPROW', 'SetFold', 'Si', 'StoPic', 'Store', 'TAN', 'TRUE', 'True', 'TeX', 'Text', 'Title', 'Unarchiv', 'WAIT', '^', '_(cm/s)', '_(ft/s)', '_(ft*lb)', '_(m/s)', '_(m/s^2)', '_(rad/s)', '_(rad/s^2)', '_(tr/min)', '_(tr/s)', '_A', '_Angstrom', '_Bq', '_Btu', '_Ci', '_F', '_F_', '_Fdy', '_G_', '_Gal', '_Gy', '_H', '_Hz', '_I0_', '_J', '_K', '_Kcal', '_MHz', '_MW', '_MeV', '_N', '_NA_', '_Ohm', '_P', '_PSun_', '_Pa', '_R', '_REarth_', '_RSun_', '_R_', '_Rankine', '_Rinfinity_', '_S', '_St', '_StdP_', '_StdT_', '_Sv', '_T', '_V', '_Vm_', '_W', '_Wb', '_Wh', '_a', '_a0_', '_acre', '_alpha_', '_angl_', '_arcmin', '_arcs', '_atm', '_au', '_b', '_bar', '_bbl', '_bblep', '_bu', '_buUS', '_c3_', '_c_', '_cal', '_cd', '_chain', '_cm', '_cm^2', '_cm^3', '_ct', '_cu', '_d', '_dB', '_deg', '_degreeF', '_dyn', '_eV', '_epsilon0_', '_epsilon0q_', '_epsilonox_', '_epsilonsi_', '_erg', '_f0_', '_fath', '_fbm', '_fc', '_fermi', '_flam', '_fm', '_ft', '_ft*lb', '_ftUS', '_ft^2', '_ft^3', '_g', '_g_', '_ga', '_galC', '_galUK', '_galUS', '_gf', '_gmol', '_gon', '_grad', '_grain', '_h', '_h_', '_ha', '_hbar_', '_hp', '_in', '_inH20', '_inHg', '_in^2', '_in^3', '_j', '_kWh', '_k_', '_kg', '_kip', '_km', '_km^2', '_knot', '_kph', '_kq_', '_l', '_lam', '_lambda0_', '_lambdac_', '_lb', '_lbf', '_lbmol', '_lbt', '_lep', '_liqpt', '_lm', '_lx', '_lyr', '_m', '_mEarth_', '_m^2', '_m^3', '_me_', '_mho', '_miUS', '_miUS^2', '_mi^2', '_mil', '_mile', '_mille', '_ml', '_mm', '_mmHg', '_mn', '_mol', '_mp_', '_mph', '_mpme_', '_mu0_', '_muB_', '_muN_', '_oz', '_ozUK', '_ozfl', '_ozt', '_pc', '_pdl', '_ph', '_phi_', '_pk', '_psi', '_ptUK', '_q_', '_qe_', '_qepsilon0_', '_qme_', '_qt', '_rad', '_rad_', '_rd', '_rem', '_rod', '_rpm', '_s', '_sb', '_sd_', '_sigma_', '_slug', '_sr', '_st', '_syr_', '_t', '_tbsp', '_tec', '_tep', '_tex', '_therm', '_ton', '_tonUK', '_torr', '_tr', '_tsp', '_twopi_', '_u', '_yd', '_yd^2', '_yd^3', '_yr', '_\xc2\xb5', '_µ', 'assert', 'affichage', 'alors', 'animate', 'animate3d', 'animation', 'approx_mode', 'archive', 'args', 'as_function_of', 'asc', 'asec', 'assign', 'backquote', 'begin', 'black', 'blanc', 'bleu', 'bloc', 'blue', 'breakpoint', 'by', 'c1oc2', 'c1op2', 'cache_tortue', 'cap', 'cap_flat_line', 'cap_round_line', 'cap_square_line', 'case', 'cat', 'catch', 'cd', 'choosebox', 'click', 'close', 'complex_mode', 'de', 'del', 'debug', 'default', 'div', 'double', 'ecris', 'efface', 'elif', 'end', 'end_for', 'end_if', 'end_while', 'epaisseur', 'epaisseur_ligne_1', 'epaisseur_ligne_2', 'epaisseur_ligne_3', 'epaisseur_ligne_4', 'epaisseur_ligne_5', 'epaisseur_ligne_6', 'epaisseur_ligne_7', 'epaisseur_point_1', 'epaisseur_point_2', 'epaisseur_point_3', 'epaisseur_point_4', 'epaisseur_point_5', 'epaisseur_point_6', 'epaisseur_point_7', 'erase', 'erase3d', 'est_cocyclique', 'est_inclus', 'et', 'faire', 'faux', 'feuille', 'ffaire', 'ffonction', 'fi', 'filled', 'fin_enregistrement', 'float', 'fonction', 'fopen', 'format', 'fpour', 'frame_3d', 'frames', 'fsi', 'ftantque', 'func', 'function', 'gauche', 'gl_ortho', 'gl_quaternion', 'gl_rotation', 'gl_shownames', 'gl_texture', 'gl_x', 'gl_x_axis_color', 'gl_x_axis_name', 'gl_x_axis_unit', 'gl_xtick', 'gl_y', 'gl_y_axis_color', 'gl_y_axis_name', 'gl_y_axis_unit', 'gl_ytick', 'gl_z', 'gl_z_axis_color', 'gl_z_axis_name', 'gl_z_axis_unit', 'gl_ztick', 'gnuplot', 'goto', 'graph2tex', 'graph3d2tex', 'graphe', 'graphe3d', 'graphe_probabiliste', 'graphe_suite', 'green', 'grid_paper', 'hidden_name', 'identifier', 'ifft', 'ifte', 'inputform', 'intersect', 'is_included', 'jusqu_a', 'jusqua', 'jusque', 'keep_algext', 'kill', 'label', 'labels', 'len', 'leve_crayon', 'line_width_1', 'line_width_2', 'line_width_3', 'line_width_4', 'line_width_5', 'line_width_6', 'line_width_7', 'lis', 'local', 'minus', 'mod', 'noir', 'nom_cache', 'non', 'od', 'option', 'otherwise', 'ou', 'pas', 'point_arret', 'point_carre', 'point_croix', 'point_div', 'point_etoile', 'point_invisible', 'point_losange', 'point_milieu', 'point_plus', 'point_point', 'point_polaire', 'point_triangle', 'point_width_1', 'point_width_2', 'point_width_3', 'point_width_4', 'point_width_5', 'point_width_6', 'point_width_7', 'pour', 'proc', 'program', 'quadrant1', 'quadrant2', 'quadrant3', 'quadrant4', 'range', 'redim', 'repeat', 'repete', 'repeter', 'replace', 'restart', 'rouge', 'saisir', 'saisir_chaine', 'sauve', 'save_history', 'scale', 'scaleadd', 'si', 'sinon', 'size', 'stack', 'step', 'switch', 'tantque', 'test', 'textinput', 'then', 'thiele', 'time', 'to', 'union', 'until', 'var', 'vector', 'vers', 'vert', 'vrai', 'watch', 'when', 'white', 'with_sqrt', 'write', 'wz_certificate', 'xor', 'yellow', '{}', '|', '||','expression']
30 |
31 |
32 | # basekeywords=['sin', 'cos', 'exp', 'tan', 'solve']
33 |
34 |
35 | # usualvars=['x','y','z','t','u','v']
36 |
37 | moremethods = ['type','zip']
38 |
39 |
40 | mostkeywordorig = ['Airy_Ai', 'Airy_Bi', 'Archive', 'BesselJ', 'BesselY', 'Beta', 'BlockDiagonal', 'Ci', 'Circle', 'Col', 'CopyVar', 'Dirac', 'Ei', 'Factor', 'GF', 'Gamma', 'Heaviside', 'JordanBlock', 'LU', 'LambertW', 'Li', 'Line', 'LineHorz', 'LineTan', 'LineVert', 'Phi', 'Pi', 'Psi', 'QR', 'RandSeed', 'Row', 'SortA', 'SortD', 'UTPC', 'UTPF', 'UTPN', 'UTPT', 'VARS', 'VAS', 'VAS_positive', 'Zeta', '_qe_', 'a2q', 'abcuv', 'about', 'abs', 'abscissa', 'accumulate_head_tail', 'acos', 'acos2asin', 'acos2atan', 'acosh', 'acot', 'acsc', 'acyclic', 'add', 'add_arc', 'add_edge', 'add_vertex', 'additionally', 'adjacency_matrix', 'adjoint_matrix', 'affix', 'algsubs', 'algvar', 'all_trig_solutions', 'allpairs_distance', 'alog10', 'altitude', 'angle', 'angle_radian', 'angleat', 'angleatraw', 'ans', 'antiprism_graph', 'apply', 'approx', 'arc', 'arcLen', 'arccos', 'arccosh', 'arclen', 'arcsin', 'arcsinh', 'arctan', 'arctanh', 'area', 'areaat', 'areaatraw', 'areaplot', 'arg', 'array', 'arrivals', 'articulation_points', 'asin', 'asin2acos', 'asin2atan', 'asinh', 'assign_edge_weights', 'assume', 'at', 'atan', 'atan2acos', 'atan2asin', 'atanh', 'atrig2ln', 'augment', 'auto_correlation', 'autosimplify', 'avance', 'avgRC', 'axes', 'back', 'backward', 'baisse_crayon', 'bandwidth', 'bar_plot', 'bartlett_hann_window', 'barycenter', 'base', 'basis', 'batons', 'bellman_ford', 'bernoulli', 'besselJ', 'besselY', 'betad', 'betad_cdf', 'betad_icdf', 'betavariate', 'bezier', 'bezout_entiers', 'biconnected_components', 'binomial', 'binomial_cdf', 'binomial_icdf', 'bins', 'bipartite', 'bipartite_matching', 'bisection_solver', 'bisector', 'bit_depth', 'bitand', 'bitor', 'bitxor', 'blackman_harris_window', 'blackman_window', 'blockmatrix', 'bohman_window', 'border', 'boxwhisker', 'brent_solver', 'bvpsolve', 'cFactor', 'cSolve', 'cZeros', 'camembert', 'canonical_form', 'canonical_labeling', 'cartesian_product', 'cauchy', 'cauchy_cdf', 'cauchy_icdf', 'cauchyd', 'cauchyd_cdf', 'cauchyd_icdf', 'cdf', 'ceil', 'ceiling', 'center', 'center2interval', 'centered_cube', 'centered_tetrahedron', 'cfactor', 'cfsolve', 'changebase', 'channel_data', 'channels', 'char', 'charpoly', 'chinrem', 'chisquare', 'chisquare_cdf', 'chisquare_icdf', 'chisquared', 'chisquared_cdf', 'chisquared_icdf', 'chisquaret', 'choice', 'cholesky', 'chr', 'chrem', 'chromatic_index', 'chromatic_number', 'chromatic_polynomial', 'circle', 'circumcircle', 'classes', 'clear', 'clique_cover', 'clique_cover_number', 'clique_number', 'clique_stats', 'clustering_coefficient', 'coeff', 'coeffs', 'col', 'colDim', 'colNorm', 'colSwap', 'coldim', 'collect', 'colnorm', 'color', 'colspace', 'colswap', 'comDenom', 'comb', 'combine', 'comment', 'common_perpendicular', 'companion', 'compare', 'complete_binary_tree', 'complete_graph', 'complete_kary_tree', 'complex', 'complex_variables', 'complexroot', 'concat', 'cond', 'condensation', 'cone', 'confrac', 'conic', 'conj', 'conjugate_equation', 'conjugate_gradient', 'connected', 'connected_components', 'cont', 'contains', 'content', 'contourplot', 'contract_edge', 'convert', 'convertir', 'convex', 'convexhull', 'convolution', 'coordinates', 'copy', 'correlation', 'cos', 'cos2sintan', 'cosh', 'cosine_window', 'cot', 'cote', 'count', 'count_eq', 'count_inf', 'count_sup', 'courbe_parametrique', 'courbe_polaire', 'covariance', 'covariance_correlation', 'cpartfrac', 'crationalroot', 'crayon', 'createwav', 'cross', 'crossP', 'cross_correlation', 'cross_point', 'cross_ratio', 'crossproduct', 'csc', 'csolve', 'csv2gen', 'cube', 'cumSum', 'cumsum', 'cumulated_frequencies', 'curl', 'current_sheet', 'curvature', 'curve', 'cyan', 'cycle2perm', 'cycle_graph', 'cycleinv', 'cycles2permu', 'cyclotomic', 'cylinder', 'dash_line', 'dashdot_line', 'dashdotdot_line', 'dayofweek', 'deSolve', 'debut_enregistrement', 'degree', 'degree_sequence', 'delcols', 'delete_arc', 'delete_edge', 'delete_vertex', 'delrows', 'deltalist', 'denom', 'densityplot', 'departures', 'derive', 'deriver', 'desolve', 'dessine_tortue', 'det', 'det_minor', 'developper', 'developper_transcendant', 'dfc', 'dfc2f', 'diag', 'diff', 'digraph', 'dijkstra', 'dim', 'directed', 'discard_edge_attribute', 'discard_graph_attribute', 'discard_vertex_attribute', 'disjoint_union', 'display', 'disque', 'disque_centre', 'distance', 'distance2', 'distanceat', 'distanceatraw', 'divergence', 'divide', 'divis', 'division_point', 'divisors', 'divmod', 'divpc', 'dnewton_solver', 'dodecahedron', 'domain', 'dot', 'dotP', 'dot_paper', 'dotprod', 'draw_arc', 'draw_circle', 'draw_graph', 'draw_line', 'draw_pixel', 'draw_polygon', 'draw_rectangle', 'droit', 'droite_tangente', 'dsolve', 'duration', 'e', 'e2r', 'ecart_type', 'ecart_type_population', 'ecm_factor', 'edge_connectivity', 'edges', 'egcd', 'egv', 'egvl', 'eigVc', 'eigVl', 'eigenvals', 'eigenvalues', 'eigenvectors', 'eigenvects', 'element', 'eliminate', 'ellipse', 'entry', 'envelope', 'epsilon', 'epsilon2zero', 'equal', 'equal2diff', 'equal2list', 'equation', 'equilateral_triangle', 'erf', 'erfc', 'error', 'est_permu', 'euler', 'euler_gamma', 'euler_lagrange', 'eval_level', 'evala', 'evalb', 'evalc', 'evalf', 'evalm', 'even', 'evolute', 'exact', 'exbisector', 'excircle', 'execute', 'exp', 'exp2list', 'exp2pow', 'exp2trig', 'expand', 'expexpand', 'expln', 'exponential', 'exponential_cdf', 'exponential_icdf', 'exponential_regression', 'exponential_regression_plot', 'exponentiald', 'exponentiald_cdf', 'exponentiald_icdf', 'export_graph', 'expovariate', 'expr', 'extend', 'extract_measure', 'extrema', 'ezgcd', 'f2nd', 'fMax', 'fMin', 'fPart', 'faces', 'facteurs_premiers', 'factor', 'factor_xn', 'factorial', 'factoriser', 'factoriser_entier', 'factoriser_sur_C', 'factors', 'fadeev', 'false', 'falsepos_solver', 'fclose', 'fcoeff', 'fdistrib', 'fft', 'fieldplot', 'find', 'find_cycles', 'findhelp', 'fisher', 'fisher_cdf', 'fisher_icdf', 'fisherd', 'fisherd_cdf', 'fisherd_icdf', 'fitdistr', 'flatten', 'float2rational', 'floor', 'flow_polynomial', 'fmod', 'foldl', 'foldr', 'fonction_derivee', 'forward', 'fourier_an', 'fourier_bn', 'fourier_cn', 'fprint', 'frac', 'fracmod', 'frame_2d', 'frequencies', 'frobenius_norm', 'froot', 'fsolve', 'fullparfrac', 'funcplot', 'function_diff', 'fxnd', 'gammad', 'gammad_cdf', 'gammad_icdf', 'gammavariate', 'gauss', 'gauss15', 'gauss_seidel_linsolve', 'gaussian_window', 'gaussjord', 'gaussquad', 'gbasis', 'gbasis_max_pairs', 'gbasis_reinject', 'gbasis_simult_primes', 'gcd', 'gcdex', 'genpoly', 'geometric', 'geometric_cdf', 'geometric_icdf', 'getDenom', 'getKey', 'getNum', 'getType', 'get_edge_attribute', 'get_edge_weight', 'get_graph_attribute', 'get_vertex_attribute', 'girth', 'gl_showaxes', 'grad', 'gramschmidt', 'graph', 'graph_automorphisms', 'graph_charpoly', 'graph_complement', 'graph_diameter', 'graph_equal', 'graph_join', 'graph_power', 'graph_rank', 'graph_spectrum', 'graph_union', 'graph_vertices', 'greduce', 'greedy_color', 'grid_graph', 'groupermu', 'hadamard', 'half_cone', 'half_line', 'halftan', 'halftan_hyp2exp', 'halt', 'hamdist', 'hamming_window', 'hann_poisson_window', 'hann_window', 'harmonic_conjugate', 'harmonic_division', 'has', 'has_arc', 'has_edge', 'hasard', 'head', 'heading', 'heapify', 'heappop', 'heappush', 'hermite', 'hessenberg', 'hessian', 'heugcd', 'hexagon', 'highlight_edges', 'highlight_subgraph', 'highlight_trail', 'highlight_vertex', 'highpass', 'hilbert', 'histogram', 'hold', 'homothety', 'horner', 'hybrid_solver', 'hybridj_solver', 'hybrids_solver', 'hybridsj_solver', 'hyp2exp', 'hyperbola', 'hypercube_graph', 'iPart', 'iabcuv', 'ibasis', 'ibpdv', 'ibpu', 'icdf', 'ichinrem', 'ichrem', 'icomp', 'icontent', 'icosahedron', 'id', 'identity', 'idivis', 'idn', 'iegcd', 'ifactor', 'ifactors', 'igamma', 'igcd', 'igcdex', 'ihermite', 'ilaplace', 'im', 'imag', 'image', 'implicitdiff', 'implicitplot', 'import_graph', 'inString', 'in_ideal', 'incidence_matrix', 'incident_edges', 'incircle', 'increasing_power', 'independence_number', 'indets', 'index', 'induced_subgraph', 'inequationplot', 'inf', 'infinity', 'insert', 'insmod', 'int', 'intDiv', 'integer', 'integrate', 'integrer', 'inter', 'interactive_odeplot', 'interactive_plotode', 'interp', 'interval', 'interval2center', 'interval_graph', 'inv', 'inverse', 'inversion', 'invisible_point', 'invlaplace', 'invztrans', 'iquo', 'iquorem', 'iratrecon', 'irem', 'isPrime', 'is_acyclic', 'is_arborescence', 'is_biconnected', 'is_bipartite', 'is_clique', 'is_collinear', 'is_concyclic', 'is_conjugate', 'is_connected', 'is_coplanar', 'is_cospherical', 'is_cut_set', 'is_cycle', 'is_directed', 'is_element', 'is_equilateral', 'is_eulerian', 'is_forest', 'is_graphic_sequence', 'is_hamiltonian', 'is_harmonic', 'is_harmonic_circle_bundle', 'is_harmonic_line_bundle', 'is_inside', 'is_integer_graph', 'is_isomorphic', 'is_isosceles', 'is_network', 'is_orthogonal', 'is_parallel', 'is_parallelogram', 'is_permu', 'is_perpendicular', 'is_planar', 'is_prime', 'is_pseudoprime', 'is_rectangle', 'is_regular', 'is_rhombus', 'is_square', 'is_strongly_connected', 'is_strongly_regular', 'is_tournament', 'is_tree', 'is_triconnected', 'is_two_edge_connected', 'is_vertex_colorable', 'is_weighted', 'ismith', 'isobarycenter', 'isom', 'isomorphic_copy', 'isopolygon', 'isosceles_triangle', 'isprime', 'ithprime', 'jacobi_equation', 'jacobi_linsolve', 'jacobi_symbol', 'jordan', 'kde', 'keep_pivot', 'ker', 'kernel', 'kernel_density', 'kneser_graph', 'kolmogorovd', 'kolmogorovt', 'kovacicsols', 'kspaths', 'l1norm', 'l2norm', 'lagrange', 'laguerre', 'laplace', 'laplacian', 'laplacian_matrix', 'latex', 'lcf_graph', 'lcm', 'lcoeff', 'ldegree', 'left', 'left_rectangle', 'legend', 'legendre', 'legendre_symbol', 'length', 'lgcd', 'lhs', 'ligne_chapeau_carre', 'ligne_chapeau_plat', 'ligne_chapeau_rond', 'ligne_polygonale', 'ligne_polygonale_pointee', 'ligne_tiret', 'ligne_tiret_point', 'ligne_tiret_pointpoint', 'ligne_trait_plein', 'limit', 'limite', 'lin', 'line', 'line_graph', 'line_inter', 'line_paper', 'line_segments', 'linear_interpolate', 'linear_regression', 'linear_regression_plot', 'lineariser', 'lineariser_trigo', 'linfnorm', 'linsolve', 'linspace', 'lis_phrase', 'list2exp', 'list2mat', 'list_edge_attributes', 'list_graph_attributes', 'list_vertex_attributes', 'listplot', 'lll', 'ln', 'lname', 'lncollect', 'lnexpand', 'locus', 'log', 'log10', 'logarithmic_regression', 'logarithmic_regression_plot', 'logb', 'logistic_regression', 'logistic_regression_plot', 'lower', 'lowest_common_ancestor', 'lowpass', 'lp_assume', 'lp_bestprojection', 'lp_binary', 'lp_binaryvariables', 'lp_breadthfirst', 'lp_depthfirst', 'lp_depthlimit', 'lp_firstfractional', 'lp_gaptolerance', 'lp_hybrid', 'lp_initialpoint', 'lp_integer', 'lp_integertolerance', 'lp_integervariables', 'lp_interiorpoint', 'lp_iterationlimit', 'lp_lastfractional', 'lp_maxcuts', 'lp_maximize', 'lp_method', 'lp_mostfractional', 'lp_nodelimit', 'lp_nodeselect', 'lp_nonnegative', 'lp_nonnegint', 'lp_pseudocost', 'lp_simplex', 'lp_timelimit', 'lp_variables', 'lp_varselect', 'lp_verbose', 'lpsolve', 'lsmod', 'lsq', 'lu', 'lvar', 'mRow', 'mRowAdd', 'magenta', 'make_directed', 'make_weighted', 'makelist', 'makemat', 'makesuite', 'makevector', 'map', 'maple2mupad', 'maple2xcas', 'maple_ifactors', 'maple_mode', 'markov', 'mat2list', 'mathml', 'matpow', 'matrix', 'matrix_norm', 'max', 'maxflow', 'maximal_independent_set', 'maximize', 'maximum_clique', 'maximum_degree', 'maximum_independent_set', 'maximum_matching', 'maxnorm', 'mean', 'median', 'median_line', 'member', 'mgf', 'mid', 'middle_point', 'midpoint', 'min', 'minimal_edge_coloring', 'minimal_spanning_tree', 'minimal_vertex_coloring', 'minimax', 'minimize', 'minimum_cut', 'minimum_degree', 'mkisom', 'mksa', 'modgcd', 'mods', 'monotonic', 'montre_tortue', 'moustache', 'moving_average', 'moyal', 'moyenne', 'mul', 'mult_c_conjugate', 'mult_conjugate', 'multinomial', 'multiplier_conjugue', 'multiplier_conjugue_complexe', 'multiply', 'mupad2maple', 'mupad2xcas', 'mycielski', 'nCr', 'nDeriv', 'nInt', 'nPr', 'nSolve', 'ncols', 'negbinomial', 'negbinomial_cdf', 'negbinomial_icdf', 'neighbors', 'network_transitivity', 'newList', 'newMat', 'newton', 'newton_solver', 'newtonj_solver', 'nextperm', 'nextprime', 'nlpsolve', 'nodisp', 'non_recursive_normal', 'nop', 'nops', 'norm', 'normal', 'normal_cdf', 'normal_icdf', 'normald', 'normald_cdf', 'normald_icdf', 'normalize', 'normalt', 'normalvariate', 'nprimes', 'nrows', 'nuage_points', 'nullspace', 'number_of_edges', 'number_of_spanning_trees', 'number_of_triangles', 'number_of_vertices', 'numer', 'octahedron', 'odd', 'odd_girth', 'odd_graph', 'odeplot', 'odesolve', 'op', 'open_polygon', 'ord', 'order', 'order_size', 'ordinate', 'orthocenter', 'orthogonal', 'osculating_circle', 'p1oc2', 'p1op2', 'pa2b2', 'pade', 'parabola', 'parallel', 'parallelepiped', 'parallelogram', 'parameq', 'parameter', 'paramplot', 'parfrac', 'pari', 'part', 'partfrac', 'parzen_window', 'pas_de_cote', 'path_graph', 'pcar', 'pcar_hessenberg', 'pcoef', 'pcoeff', 'pencolor', 'pendown', 'penup', 'perimeter', 'perimeterat', 'perimeteratraw', 'periodic', 'perm', 'perminv', 'permu2cycles', 'permu2mat', 'permuorder', 'permute_vertices', 'perpen_bisector', 'perpendicular', 'petersen_graph', 'peval', 'pi', 'piecewise', 'pivot', 'pixoff', 'pixon', 'planar', 'plane', 'plane_dual', 'playsnd', 'plex', 'plot', 'plot3d', 'plotarea', 'plotcdf', 'plotcontour', 'plotdensity', 'plotfield', 'plotfunc', 'plotimplicit', 'plotinequation', 'plotlist', 'plotode', 'plotparam', 'plotpolar', 'plotproba', 'plotseq', 'plotspectrum', 'plotwav', 'plus_point', 'pmin', 'point', 'point2d', 'point3d', 'poisson', 'poisson_cdf', 'poisson_icdf', 'poisson_window', 'polar', 'polar_coordinates', 'polar_point', 'polarplot', 'pole', 'poly2symb', 'polyEval', 'polygon', 'polygone_rempli', 'polygonplot', 'polygonscatterplot', 'polyhedron', 'polynom', 'polynomial_regression', 'polynomial_regression_plot', 'position', 'poslbdLMQ', 'posubLMQ', 'potential', 'pow2exp', 'power_regression', 'power_regression_plot', 'powermod', 'powerpc', 'powexpand', 'powmod', 'prepend', 'preval', 'prevperm', 'prevprime', 'primpart', 'printf', 'prism', 'prism_graph', 'product', 'projection', 'proot', 'propFrac', 'propfrac', 'psrgcd', 'ptayl', 'purge', 'pwd', 'pyramid', 'python_compat', 'q2a', 'qr', 'quadric', 'quadrilateral', 'quantile', 'quartile1', 'quartile3', 'quartiles', 'quest', 'quo', 'quorem', 'quote', 'r2e', 'radical_axis', 'radius', 'ramene', 'rand', 'randMat', 'randNorm', 'randPoly', 'randbetad', 'randbinomial', 'randchisquare', 'randexp', 'randfisher', 'randgammad', 'randgeometric', 'randint', 'randmarkov', 'randmatrix', 'randmultinomial', 'randnorm', 'random', 'random_bipartite_graph', 'random_digraph', 'random_graph', 'random_network', 'random_planar_graph', 'random_regular_graph', 'random_sequence_graph', 'random_tournament', 'random_tree', 'random_variable', 'randperm', 'randpoisson', 'randpoly', 'randseed', 'randstudent', 'randvar', 'randvector', 'randweibulld', 'rank', 'ranm', 'ranv', 'rassembler_trigo', 'rat_jordan', 'rational', 'rationalroot', 'ratnormal', 'rcl', 'rdiv', 're', 'read', 'readrgb', 'readwav', 'real', 'realroot', 'reciprocation', 'rectangle', 'rectangle_droit', 'rectangle_gauche', 'rectangle_plein', 'rectangular_coordinates', 'recule', 'red', 'reduced_conic', 'reduced_quadric', 'ref', 'reflection', 'regroup', 'relabel_vertices', 'reliability_polynomial', 'rem', 'remain', 'remove', 'reorder', 'resample', 'residue', 'resoudre', 'resoudre_dans_C', 'resoudre_systeme_lineaire', 'resultant', 'reverse', 'reverse_graph', 'reverse_rsolve', 'revert', 'revlex', 'revlist', 'rgb', 'rhombus', 'rhombus_point', 'rhs', 'riemann_window', 'right', 'right_rectangle', 'right_triangle', 'risch', 'rm_a_z', 'rm_all_vars', 'rmbreakpoint', 'rmmod', 'rmwatch', 'romberg', 'rombergm', 'rombergt', 'rond', 'root', 'rootof', 'roots', 'rotate', 'rotation', 'round', 'row', 'rowAdd', 'rowDim', 'rowNorm', 'rowSwap', 'rowdim', 'rownorm', 'rowspace', 'rowswap', 'rref', 'rsolve', 'same', 'sample', 'samplerate', 'sans_factoriser', 'saute', 'scalarProduct', 'scalar_product', 'scatterplot', 'schur', 'sec', 'secant_solver', 'segment', 'seidel_spectrum', 'seidel_switch', 'select', 'semi_augment', 'seq', 'seqplot', 'seqsolve', 'sequence_graph', 'series', 'set_edge_attribute', 'set_edge_weight', 'set_graph_attribute', 'set_pixel', 'set_vertex_attribute', 'set_vertex_positions', 'shift', 'shift_phase', 'shortest_path', 'show_pixels', 'shuffle', 'sierpinski_graph', 'sign', 'signature', 'signe', 'similarity', 'simp2', 'simplex_reduce', 'simplifier', 'simplify', 'simpson', 'simult', 'sin', 'sin2costan', 'sincos', 'single_inter', 'sinh', 'sizes', 'slope', 'slopeat', 'slopeatraw', 'smith', 'smod', 'snedecor', 'snedecor_cdf', 'snedecor_icdf', 'snedecord', 'snedecord_cdf', 'snedecord_icdf', 'solid_line', 'solve', 'somme', 'sommet', 'sort', 'sorta', 'sortd', 'sorted', 'soundsec', 'spanning_tree', 'sphere', 'spline', 'split', 'spring', 'sq', 'sqrfree', 'sqrt', 'square', 'square_point', 'srand', 'sst', 'sst_in', 'st_ordering', 'star_graph', 'star_point', 'start', 'stdDev', 'stddev', 'stddevp', 'steffenson_solver', 'stereo2mono', 'str', 'strongly_connected_components', 'student', 'student_cdf', 'student_icdf', 'studentd', 'studentt', 'sturm', 'sturmab', 'sturmseq', 'style', 'subMat', 'subdivide_edges', 'subgraph', 'subs', 'subsop', 'subst', 'substituer', 'subtype', 'sum', 'sum_riemann', 'suppress', 'surd', 'svd', 'swapcol', 'swaprow', 'switch_axes', 'sylvester', 'symb2poly', 'symbol', 'syst2mat', 'tCollect', 'tExpand', 'table', 'tablefunc', 'tableseq', 'tabvar', 'tail', 'tan', 'tan2cossin2', 'tan2sincos', 'tan2sincos2', 'tangent', 'tangente', 'tanh', 'taux_accroissement', 'taylor', 'tchebyshev1', 'tchebyshev2', 'tcoeff', 'tcollect', 'tdeg', 'tensor_product', 'tetrahedron', 'texpand', 'thickness', 'threshold', 'throw', 'title', 'titre', 'tlin', 'tonnetz', 'topologic_sort', 'topological_sort', 'torus_grid_graph', 'total_degree', 'tourne_droite', 'tourne_gauche', 'tpsolve', 'trace', 'trail', 'trail2edges', 'trames', 'tran', 'transitive_closure', 'translation', 'transpose', 'trapeze', 'trapezoid', 'traveling_salesman', 'tree', 'tree_height', 'triangle', 'triangle_paper', 'triangle_plein', 'triangle_point', 'triangle_window', 'trig2exp', 'trigcos', 'trigexpand', 'triginterp', 'trigsimplify', 'trigsin', 'trigtan', 'trn', 'true', 'trunc', 'truncate', 'truncate_graph', 'tsimplify', 'tuer', 'tukey_window', 'tutte_polynomial', 'two_edge_connected_components', 'ufactor', 'ugamma', 'unapply', 'unarchive', 'underlying_graph', 'unfactored', 'uniform', 'uniform_cdf', 'uniform_icdf', 'uniformd', 'uniformd_cdf', 'uniformd_icdf', 'unitV', 'unquote', 'upper', 'user_operator', 'usimplify', 'valuation', 'vandermonde', 'variables_are_files', 'variance', 'version', 'vertex_connectivity', 'vertex_degree', 'vertex_distance', 'vertex_in_degree', 'vertex_out_degree', 'vertices', 'vertices_abc', 'vertices_abca', 'vpotential', 'web_graph', 'weibull', 'weibull_cdf', 'weibull_icdf', 'weibulld', 'weibulld_cdf', 'weibulld_icdf', 'weibullvariate', 'weight_matrix', 'weighted', 'weights', 'welch_window', 'wheel_graph', 'widget_size', 'wilcoxonp', 'wilcoxons', 'wilcoxont', 'with_sqrt', 'writergb', 'writewav', 'xcas_mode', 'xyztrange', 'zeros', 'ztrans']
41 |
42 |
43 | if __name__ == "__main__":
44 | # The file aide_cas.txt should contain one line by keywords+ its
45 | # synonyms. The docstring for this file contains instructions for
46 | # building it.
47 | with open('aide_cas.txt') as f:
48 | mostkeywords = f.read().split()
49 |
50 | missing = set(mostkeywordorig).difference(mostkeywords)
51 | print("Missing keywords: ", missing)
52 | newkeywords = (set(mostkeywords).difference(mostkeywordorig)).difference(toremove+blacklist)
53 | print("\nNew keywords:", newkeywords)
54 |
55 | #undocumented keywords
56 | #undocumented=['posubLMQ','poslbdLMQ','VAS_positive','VAS']
57 | undocumented = []
58 |
59 | mostkeywords = mostkeywords+undocumented
60 |
61 | mostkeywords = set(mostkeywords).difference(toremove)
62 | mostkeywords = set(mostkeywords).difference(blacklist)
63 | mostkeywords = set(mostkeywords).difference(moremethods)
64 | mostkeywords = list(mostkeywords)
65 | mostkeywords.sort()
66 |
67 | # building auto-methods.pxi
68 | Mi = open("auto-methods.pxi","w")
69 | Mi.write("# file auto generated by mkkeywords.py\n")
70 | s = 'cdef class GiacMethods_base:\n'
71 | s += ' """\n'
72 | s += ' Wrapper for a giac ``gen`` containing auto-generated methods.\n'
73 | s += '\n'
74 | s += ' This class does not manage the ``gen`` inside in any way.\n'
75 | s += ' It is just a dumb wrapper. You almost certainly want to\n'
76 | s += ' use the derived class :class:`Pygen` instead.\n'
77 | s += ' """\n\n'
78 | Mi.write(s)
79 |
80 | for i in mostkeywords + moremethods:
81 | p = Popen(["cas_help", i],
82 | stdout=PIPE,
83 | stderr=PIPE,
84 | universal_newlines=True)
85 | doc = p.communicate()[0]
86 |
87 | # The Giac docs include as their first line, "Help for Foo:"
88 | # which is a bit redundant.
89 | doc = doc.replace(f"Help for {i}:", "")
90 | doc = "\n ".join(doc.splitlines()) # indent each line
91 |
92 | s = " def " + i + "(self,*args):\n"
93 | s += " r'''\n"
94 | s += " From Giac's documentation:\n"
95 | s += f" {doc}\n"
96 | s += " '''\n"
97 | s += f" return GiacMethods['{i}'](self,*args)\n\n"
98 | Mi.write(s)
99 |
100 | Mi.close()
101 |
102 | # building keywords.pxi
103 | with open("keywords.pxi", "w") as Fi:
104 | Fi.write("# file auto generated by mkkeywords.py\n")
105 | Fi.write("blacklist = " + str(blacklist) + "\n\n")
106 | Fi.write("toremove = " + str(toremove) + "\n\n")
107 | Fi.write("moremethods = " + str(moremethods) + "\n\n")
108 | Fi.write("mostkeywords = " + str(mostkeywords) + "\n\n")
109 |
110 | with open("newkeyword.pxi", "w") as Fi:
111 | Fi.write(str(list(set(mostkeywords).difference(mostkeywordorig))))
112 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/src/sagemath_giac/giac.pyx:
--------------------------------------------------------------------------------
1 | r"""
2 | Interface to the c++ giac library.
3 |
4 | Giac is a general purpose Computer algebra system by Bernard Parisse
5 | released under GPLv3.
6 |
7 | - http://www-fourier.ujf-grenoble.fr/~parisse/giac.html
8 | - It is build on C and C++ libraries: NTL (arithmetic), GSL (numerics), GMP
9 | (big integers), MPFR (bigfloats)
10 | - It provides fast algorithms for multivariate polynomial operations
11 | (product, GCD, factorisation) and
12 | - symbolic computations: solver, simplifications, limits/series, integration,
13 | summation...
14 | - Linear Algebra with numerical or symbolic coefficients.
15 |
16 | AUTHORS:
17 |
18 | - Frederic Han (2013-09-23): initial version
19 | - Vincent Delecroix (2020-09-02): move inside Sage source code
20 |
21 | EXAMPLES:
22 |
23 | The class Pygen is the main tool to interact from python/sage with the c++
24 | library giac via cython. The initialisation of a Pygen just create an object
25 | in giac, but the mathematical computation is not done. This class is mainly
26 | for cython users. Here A is a Pygen element, and it is ready for any giac
27 | function.::
28 |
29 | >>> from sagemath_giac.giac import *
30 | >>> A = Pygen('2+2')
31 | >>> A
32 | 2+2
33 | >>> A.eval()
34 | 4
35 |
36 | In general, you may prefer to directly create a Pygen and execute the
37 | evaluation in giac. This is exactly the meaning of the :func:`libgiac`
38 | function.::
39 |
40 | >>> a = libgiac('2+2')
41 | >>> a
42 | 4
43 | >>> isinstance(a, Pygen)
44 | True
45 |
46 | Most common usage of this package in sage will be with the libgiac() function.
47 | This function is just the composition of the Pygen initialisation and the
48 | evaluation of this object in giac.::
49 |
50 | >>> x,y,z = libgiac('x,y,z') # add some giac objects
51 | >>> f = (x+y*3)/(x+z+1)**2 - (x+z+1)**2 / (x+y*3)
52 | >>> f.factor()
53 | (3*y-x^2-2*x*z-x-z^2-2*z-1)*(3*y+x^2+2*x*z+3*x+z^2+2*z+1)/((x+z+1)^2*(3*y+x))
54 | >>> f.normal()
55 | (-x^4-4*x^3*z-4*x^3-6*x^2*z^2-12*x^2*z-5*x^2+6*x*y-4*x*z^3-12*x*z^2-12*x*z-4*x+9*y^2-z^4-4*z^3-6*z^2-4*z-1)/(x^3+3*x^2*y+2*x^2*z+2*x^2+6*x*y*z+6*x*y+x*z^2+2*x*z+x+3*y*z^2+6*y*z+3*y)
56 |
57 | Some settings of giac are available via the ``giacsettings``
58 | element. (Ex: maximal number of threads in computations, allowing
59 | probabilistic algorithms or not...::
60 |
61 | >>> from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
62 | >>> from sage.rings.rational_field import QQ
63 | >>> from sage.rings.ideal import Katsura as KatsuraIdeal
64 | >>> R = PolynomialRing(QQ,8,'x')
65 | >>> I = KatsuraIdeal(R,8)
66 | >>> giacsettings.proba_epsilon = 1e-15 # faster, but can fail
67 | >>> Igiac = libgiac(I.gens());
68 | >>> Bgiac = Igiac.gbasis([R.gens()],'revlex')
69 | >>> len(Bgiac)
70 | 74
71 | >>> giacsettings.proba_epsilon = 0 # slower, but more reliable
72 | >>> Igiac = libgiac(I.gens())
73 | >>> Bgiac = Igiac.gbasis([R.gens()],'revlex')
74 | >>> len(Bgiac)
75 | 74
76 | >>> giacsettings.proba_epsilon = 1e-15
77 |
78 | ::
79 |
80 | >>> x = libgiac('x')
81 | >>> f = libgiac(1) / (libgiac.sin(x*5)+2)
82 | >>> f.int()
83 | 2/5/sqrt(3)*(atan((-sqrt(3)*sin(5*x)+cos(5*x)+2*sin(5*x)+1)/(sqrt(3)*cos(5*x)+sqrt(3)-2*cos(5*x)+sin(5*x)+2))+5*x/2)
84 | >>> f.series(x,0,3)
85 | 1/2-5/4*x+25/8*x^2-125/48*x^3+x^4*order_size(x)
86 | >>> (libgiac.sqrt(5)+libgiac.pi).approx(100)
87 | 5.377660631089582934871817052010779119637787758986631545245841837718337331924013898042449233720899343
88 |
89 | TESTS::
90 |
91 | >>> from sagemath_giac.giac import libgiac
92 | >>> libgiac(3**100)
93 | 515377520732011331036461129765621272702107522001
94 | >>> libgiac(-3**100)
95 | -515377520732011331036461129765621272702107522001
96 | >>> libgiac(-11**1000)
97 | -2469932918005826334124088385085221477709733385238396234869182951830739390375433175367866116456946191973803561189036523363533798726571008961243792655536655282201820357872673322901148243453211756020067624545609411212063417307681204817377763465511222635167942816318177424600927358163388910854695041070577642045540560963004207926938348086979035423732739933235077042750354729095729602516751896320598857608367865475244863114521391548985943858154775884418927768284663678512441565517194156946312753546771163991252528017732162399536497445066348868438762510366191040118080751580689254476068034620047646422315123643119627205531371694188794408120267120500325775293645416335230014278578281272863450085145349124727476223298887655183167465713337723258182649072572861625150703747030550736347589416285606367521524529665763903537989935510874657420361426804068643262800901916285076966174176854351055183740078763891951775452021781225066361670593917001215032839838911476044840388663443684517735022039957481918726697789827894303408292584258328090724141496484460001
98 |
99 | Ensure that signed infinities get converted correctly::
100 |
101 | >>> from sage.rings.infinity import Infinity
102 | >>> libgiac(+Infinity)
103 | +infinity
104 | >>> libgiac(-Infinity)
105 | -infinity
106 |
107 | .. SEEALSO::
108 |
109 | ``libgiac``, ``giacsettings``, ``Pygen``,``loadgiacgen``
110 |
111 |
112 | GETTING HELP:
113 |
114 | - To obtain some help on a giac keyword use the help() method. In sage the
115 | htmlhelp() method for Pygen element is disabled. Just use the ? or .help()
116 | method.
117 |
118 | - You can find full html documentation about the **giac** functions at:
119 |
120 | - https://www-fourier.ujf-grenoble.fr/~parisse/giac/doc/en/cascmd_en/
121 |
122 | - https://www-fourier.ujf-grenoble.fr/~parisse/giac/doc/fr/cascmd_fr/
123 |
124 | - https://www-fourier.ujf-grenoble.fr/~parisse/giac/doc/el/cascmd_el/
125 |
126 | """
127 | # ****************************************************************************
128 | # Copyright (C) 2012, Frederic Han
129 | # 2020, Vincent Delecroix <20100.delecroix@gmail.com>
130 | #
131 | # Distributed under the terms of the GNU General Public License (GPL)
132 | # as published by the Free Software Foundation; either version 2 of
133 | # the License, or (at your option) any later version.
134 | # https://www.gnu.org/licenses/
135 | #*****************************************************************************
136 |
137 | from cysignals.signals cimport *
138 | from gmpy2 cimport import_gmpy2, mpz_set
139 | from sys import maxsize as Pymaxint, version_info as Pyversioninfo
140 | import os
141 | import math
142 |
143 | # sage includes
144 | from sage.ext.stdsage cimport PY_NEW
145 | from sage.rings.integer_ring import ZZ
146 | from sage.rings.rational_field import QQ
147 | from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
148 | from sage.rings.integer cimport Integer
149 | from sage.rings.infinity import AnInfinity
150 | from sage.rings.rational cimport Rational
151 | from sage.structure.element cimport Matrix
152 |
153 | from sage.symbolic.expression import symbol_table
154 | from sage.calculus.calculus import symbolic_expression_from_string, SR_parser_giac
155 | from sage.symbolic.ring import SR
156 | from sage.symbolic.expression import Expression
157 | from sage.symbolic.expression_conversions import InterfaceInit
158 | from sage.interfaces.giac import giac
159 |
160 |
161 | # initialize the gmpy2 C-API
162 | import_gmpy2()
163 |
164 |
165 | # Python3 compatibility ############################
166 | def encstring23(s):
167 | return bytes(s, 'UTF-8')
168 | # End of Python3 compatibility #####################
169 |
170 |
171 | ########################################################
172 | # A global context pointer. One by giac session.
173 | ########################################################
174 | cdef context * context_ptr = new context()
175 |
176 | # Some global variables for optimisation
177 | GIACNULL = Pygen('NULL')
178 |
179 | # Create a giac setting instance
180 | giacsettings = GiacSetting()
181 | Pygen('I:=sqrt(-1)').eval() # WTF?
182 |
183 | # A function to convert SR Expression with defined giac conversion to a string
184 | # for giac/libgiac.
185 | # NB: We want to do this without starting an external giac program and
186 | # self._giac_() does.
187 | SRexpressiontoGiac = InterfaceInit(giac)
188 |
189 |
190 | #######################################################
191 | # The wrapper to eval with giac
192 | #######################################################
193 | # in sage we don't export the giac function. We replace it by libgiac
194 | def _giac(s):
195 | """
196 | This function evaluate a python/sage object with the giac
197 | library. It creates in python/sage a Pygen element and evaluate it
198 | with giac:
199 |
200 | EXAMPLES::
201 |
202 | >>> from sagemath_giac.giac import libgiac
203 | >>> x,y = libgiac('x,y')
204 | >>> (x + y*2).cos().texpand()
205 | cos(x)*(2*cos(y)^2-1)-sin(x)*2*cos(y)*sin(y)
206 |
207 | Coercion, Pygen and internal giac variables: The most useful
208 | objects will be the Python object of type Pygen::
209 |
210 | >>> x,y,z = libgiac('x,y,z')
211 | >>> f = sum([x[i] for i in range(5)], libgiac(0))**15/(y+z)
212 | >>> f.coeff(x[0],12)
213 | (455*(x[1])^3+1365*(x[1])^2*x[2]+1365*(x[1])^2*x[3]+1365*(x[1])^2*x[4]+1365*x[1]*(x[2])^2+2730*x[1]*x[2]*x[3]+2730*x[1]*x[2]*x[4]+1365*x[1]*(x[3])^2+2730*x[1]*x[3]*x[4]+1365*x[1]*(x[4])^2+455*(x[2])^3+1365*(x[2])^2*x[3]+1365*(x[2])^2*x[4]+1365*x[2]*(x[3])^2+2730*x[2]*x[3]*x[4]+1365*x[2]*(x[4])^2+455*(x[3])^3+1365*(x[3])^2*x[4]+1365*x[3]*(x[4])^2+455*(x[4])^3)/(y+z)
214 |
215 | Warning: The complex number sqrt(-1) is available in SageMath as
216 | ``I``, but it may appears as ``i``::
217 |
218 | >>> from sage.rings.imaginary_unit import I
219 | >>> libgiac((libgiac.sqrt(3)*I + 1)**3).normal()
220 | -8
221 | >>> libgiac(1+I)
222 | 1+i
223 |
224 | Python integers and reals can be directly converted to giac.::
225 |
226 | >>> libgiac(2**1024).nextprime()
227 | 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137859
228 | >>> libgiac(1.234567).erf().approx(10)
229 | 0.9191788641
230 |
231 | The Python object ``y`` defined above is of type Pygen. It is not
232 | an internal giac variable. (Most of the time you won't need to use
233 | internal giac variables)::
234 |
235 | >>> libgiac('y:=1'); y
236 | 1
237 | y
238 | >>> libgiac.purge('y')
239 | 1
240 | >>> libgiac('y')
241 | y
242 |
243 | There are some natural coercion to Pygen elements::
244 |
245 | >>> libgiac.pi > 3.14
246 | True
247 | >>> libgiac.pi > 3.15
248 | False
249 | >>> libgiac(3) == 3
250 | True
251 |
252 | Linear Algebra. In Giac/Xcas vectors are just lists and matrices
253 | are lists of list::
254 |
255 | >>> x,y = libgiac('x,y')
256 | >>> A = libgiac([[1,2],[3,4]]) # giac matrix
257 | >>> v = libgiac([x,y]); v # giac vector
258 | [x,y]
259 | >>> A*v # matrix-vector product
260 | [x+2*y,3*x+4*y]
261 | >>> v*v # dot product
262 | x*x+y*y
263 |
264 | Remark that ``w=giac([[x],[y]])`` is a matrix of 1 column and 2
265 | rows. It is not a vector so w*w doesn't make sense.::
266 |
267 | >>> w = libgiac([[x],[y]])
268 | >>> w.transpose()*w
269 | matrix[[x*x+y*y]]
270 |
271 | In sage, changing an entry doesn't create a new matrix (see also
272 | the doc of ``Pygen.__setitem__``)::
273 |
274 | >>> B1 = A
275 | >>> B1[0,0]=43; B1 # in place affectation changes both B1 and A
276 | [[43,2],[3,4]]
277 | >>> A
278 | [[43,2],[3,4]]
279 | >>> A[0][0]=A[0][0]+1; A # similar as A[0,0]=A[0,0]+1
280 | [[44,2],[3,4]]
281 | >>> A.pcar(x) # compute the characteristic polynomial of A
282 | x^2-48*x+170
283 | >>> B2=A.copy() # use copy to create another object
284 | >>> B2[0,0]=55; B2 # here A is not modified
285 | [[55,2],[3,4]]
286 | >>> A
287 | [[44,2],[3,4]]
288 |
289 | Sparse Matrices are available via the table function::
290 |
291 | >>> A = libgiac.table(()); A # create an empty giac table
292 | table(
293 | )
294 | >>> A[2,3] = 33; A[0,2] = '2/7' # set nonzero entries of the sparse matrix
295 | >>> A*A # basic matrix operation are supported with sparse matrices
296 | table(
297 | (0,3) = 66/7
298 | )
299 | >>> D = libgiac.diag([22,3,'1/7']); D # some diagonal matrix
300 | [[22,0,0],[0,3,0],[0,0,1/7]]
301 | >>> libgiac.table(D) # to create a sparse matrix from an ordinary one
302 | table(
303 | (0,0) = 22,
304 | (1,1) = 3,
305 | (2,2) = 1/7
306 | )
307 |
308 | But many matrix functions apply only with ordinary matrices so
309 | need conversions::
310 |
311 | >>> B1 = A.matrix(); B1 # convert the sparse matrix to a matrix, but the size is minimal
312 | [[0,0,2/7,0],[0,0,0,0],[0,0,0,33]]
313 | >>> B2 = B1.redim(4,4) # so we may need to resize B1
314 | >>> B2.pmin(x)
315 | x^3
316 |
317 | Lists of Pygen and Giac lists. Here l1 is a giac list and l2 is a
318 | python list of Pygen type objects::
319 |
320 | >>> l1 = libgiac(range(10))
321 | >>> l2 = [libgiac(1)/(i**2+1) for i in l1]
322 | >>> sum(l2, libgiac(0))
323 | 33054527/16762850
324 |
325 | So l1+l1 is done in giac and means a vector addition. But l2+l2 is
326 | done in Python so it is the list concatenation::
327 |
328 | >>> l1+l1
329 | [0,2,4,6,8,10,12,14,16,18]
330 | >>> l2+l2
331 | [1, 1/2, 1/5, 1/10, 1/17, 1/26, 1/37, 1/50, 1/65, 1/82, 1, 1/2, 1/5, 1/10, 1/17, 1/26, 1/37, 1/50, 1/65, 1/82]
332 |
333 | Here V is not a Pygen element. We need to push it to giac to use a
334 | giac method like dim, or we need to use an imported function::
335 |
336 | >>> V = [ [x[i]**j for i in range(8)] for j in range(8)]
337 | >>> libgiac(V).dim()
338 | [8,8]
339 | >>> libgiac.det_minor(V).factor()
340 | (x[6]-(x[7]))*(x[5]-(x[7]))*(x[5]-(x[6]))*(x[4]-(x[7]))*(x[4]-(x[6]))*(x[4]-(x[5]))*(x[3]-(x[7]))*(x[3]-(x[6]))*(x[3]-(x[5]))*(x[3]-(x[4]))*(x[2]-(x[7]))*(x[2]-(x[6]))*(x[2]-(x[5]))*(x[2]-(x[4]))*(x[2]-(x[3]))*(x[1]-(x[7]))*(x[1]-(x[6]))*(x[1]-(x[5]))*(x[1]-(x[4]))*(x[1]-(x[3]))*(x[1]-(x[2]))*(x[0]-(x[7]))*(x[0]-(x[6]))*(x[0]-(x[5]))*(x[0]-(x[4]))*(x[0]-(x[3]))*(x[0]-(x[2]))*(x[0]-(x[1]))
341 |
342 | Modular objects with ``%``::
343 |
344 | >>> V = libgiac.ranm(5,6) % 2
345 | >>> V.ker().rowdim()+V.rank()
346 | 6
347 | >>> a = libgiac(7)%3
348 | >>> a
349 | 1 % 3
350 | >>> a % 0
351 | 1
352 | >>> 7 % 3
353 | 1
354 |
355 | Do not confuse with the python integers::
356 |
357 | >>> type(7 % 3) == type(a)
358 | False
359 | >>> type(a) == type(7 % 3)
360 | False
361 |
362 | Syntax with reserved or unknown Python/sage symbols. In general
363 | equations needs symbols such as ``=``, ``<`` or ``>`` that have
364 | another meaning in Python or Sage. So those objects must be
365 | quoted::
366 |
367 | >>> x = libgiac('x')
368 | >>> (libgiac.sin(x*3)*2 + 1).solve(x).simplify()
369 | list[-pi/18,7*pi/18]
370 |
371 | >>> libgiac.solve('x^3-x>x',x)
372 | list[((x>(-sqrt(2))) and (x<0)),x>(sqrt(2))]
373 |
374 | You can also add some hypothesis to a giac symbol::
375 |
376 | >>> libgiac.assume('x>-pi && x>> libgiac.solve('sin(3*x)>2*sin(x)',x)
379 | list[((x>(-5*pi/6)) and (x<(-pi/6))),((x>0) and (x<(pi/6))),((x>(5*pi/6)) and (x>> libgiac.purge('x')
384 | assume[[],[line[-pi,pi]],[-pi,pi]]
385 | >>> libgiac.solve('x>0')
386 | list[x>0]
387 |
388 | Same problems with the ``..``::
389 |
390 | >>> x = libgiac('x')
391 | >>> f = libgiac(1)/(libgiac.cos(x*4)+5)
392 | >>> f.int()
393 | 1/2/(2*sqrt(6))*(atan((-sqrt(6)*sin(4*x)+2*sin(4*x))/(sqrt(6)*cos(4*x)+sqrt(6)-2*cos(4*x)+2))+4*x/2)
394 | >>> libgiac.fMax(f,'x=-0..pi').simplify()
395 | pi/4,3*pi/4
396 | >>> libgiac.sum(libgiac(1)/(x**2+1),'x=0..infinity').simplify()
397 | (pi*exp(pi)^2+pi+exp(pi)^2-1)/(2*exp(pi)^2-2)
398 |
399 | From giac to sage. One can convert a Pygen element to sage with
400 | the ``sage`` method::
401 |
402 | >>> L = libgiac('[1,sqrt(5),[1.3,x]]')
403 | >>> L.sage() # All entries are converted recursively
404 | [1, sqrt(5), [1.30000000000000, x]]
405 |
406 | >>> from sage.symbolic.ring import SR
407 | >>> from sage.matrix.constructor import matrix
408 | >>> n = SR.symbol('n')
409 | >>> A = matrix([[1,2],[-1,1]])
410 | >>> B = libgiac(A).matpow(n) # We compute the symbolic power on A via libgiac
411 | >>> C = matrix(SR,B); C # We convert B to sage
412 | [ 1/2*(I*sqrt(2) + 1)^n + 1/2*(-I*sqrt(2) + 1)^n -1/2*I*sqrt(2)*(I*sqrt(2) + 1)^n + 1/2*I*sqrt(2)*(-I*sqrt(2) + 1)^n]
413 | [ 1/4*I*sqrt(2)*(I*sqrt(2) + 1)^n - 1/4*I*sqrt(2)*(-I*sqrt(2) + 1)^n 1/2*(I*sqrt(2) + 1)^n + 1/2*(-I*sqrt(2) + 1)^n]
414 | >>> (C.subs(n=3)-A**3).expand()
415 | [0 0]
416 | [0 0]
417 |
418 |
419 | **MEMENTO of usual GIAC functions**:
420 |
421 | - *Expand with simplification*
422 |
423 | * ``ratnormal``, ``normal``, ``simplify`` (from the fastest to the most sophisticated)
424 |
425 | * NB: ``expand`` function doesn't regroup nor cancel terms, so it could be slow. (pedagogical purpose only?)
426 |
427 | - *Factor/Regroup*
428 |
429 | * ``factor``, ``factors``, ``regroup``, ``cfactor``, ``ifactor``
430 |
431 | - *Misc*
432 |
433 | * ``unapply``, ``op``, ``subst``
434 |
435 | - *Polynomials/Fractions*
436 |
437 | * ``coeff``, ``gbasis``, ``greduce``, ``lcoeff``, ``pcoeff``, ``canonical_form``,
438 |
439 | * ``proot``, ``poly2symb``, ``symb2poly``, ``posubLMQ``, ``poslbdLMQ``, ``VAS``, ``tcoeff``, ``valuation``
440 |
441 | * ``gcd``, ``egcd``, ``lcm``, ``quo``, ``rem``, ``quorem``, ``abcuv``, ``chinrem``,
442 |
443 | * ``peval``, ``horner``, ``lagrange``, ``ptayl``, ``spline``, ``sturm``, ``sturmab``
444 |
445 | * ``partfrac``, ``cpartfrac``
446 |
447 | - *Memory/Variables*
448 |
449 | * ``assume``, ``about``, ``purge``, ``ans``
450 |
451 | - *Calculus/Exact*
452 |
453 | * ``linsolve``, ``solve``, ``csolve``, ``desolve``, ``seqsolve``, ``reverse_rsolve``, ``matpow``
454 |
455 | * ``limit``, ``series``, ``sum``, ``diff``, ``fMax``, ``fMin``,
456 |
457 | * ``integrate``, ``subst``, ``ibpdv``, ``ibpu``, ``preval``
458 |
459 | - *Calculus/Exp, Log, powers*
460 |
461 | * ``exp2pow``, ``hyp2exp``, ``expexpand``, ``lin``, ``lncollect``, ``lnexpand``, ``powexpand``, ``pow2exp``
462 |
463 | - *Trigo*
464 |
465 | * ``trigexpand``, ``tsimplify``, ``tlin``, ``tcollect``,
466 |
467 | * ``halftan``, ``cos2sintan``, ``sin2costan``, ``tan2sincos``, ``tan2cossin2``, ``tan2sincos2``, ``trigcos``, ``trigsin``, ``trigtan``, ``shift_phase``
468 |
469 | * ``exp2trig``, ``trig2exp``
470 |
471 | * ``atrig2ln``, ``acos2asin``, ``acos2atan``, ``asin2acos``, ``asin2atan``, ``atan2acos``, ``atan2asin``
472 |
473 | - *Linear Algebra*
474 |
475 | * ``identity``, ``matrix``, ``makemat``, ``syst2mat``, ``matpow``, ``table``, ``redim``
476 |
477 | * ``det``, ``det_minor``, ``rank``, ``ker``, ``image``, ``rref``, ``simplex_reduce``,
478 |
479 | * ``egv``, ``egvl``, ``eigenvalues``, ``pcar``, ``pcar_hessenberg``, ``pmin``,
480 |
481 | * ``jordan``, ``adjoint_matrix``, ``companion``, ``hessenberg``, ``transpose``,
482 |
483 | * ``cholesky``, ``lll``, ``lu``, ``qr``, ``svd``, ``a2q``, ``gauss``, ``gramschmidt``,
484 | ``q2a``, ``isom``, ``mkisom``
485 |
486 |
487 | - *Finite Fields*
488 |
489 | * ``%``, ``% 0``, ``mod``, ``GF``, ``powmod``
490 |
491 |
492 | - *Integers*
493 |
494 | * ``gcd``, ``iabcuv``, ``ichinrem``, ``idivis``, ``iegcd``,
495 |
496 | * ``ifactor``, ``ifactors``, ``iquo``, ``iquorem``, ``irem``,
497 |
498 | * ``is_prime, is_pseudoprime``, ``lcm``, ``mod``, ``nextprime``, ``pa2b2``, ``prevprime``,
499 | ``smod``, ``euler``, ``fracmod``
500 |
501 | - *List*
502 |
503 | * ``append``, ``accumulate_head_tail``, ``concat``, ``head``, ``makelist``, ``member``, ``mid``, ``revlist``, ``rotate``, ``shift``, ``size``, ``sizes``, ``sort``, ``suppress``, ``tail``
504 |
505 | - *Set*
506 |
507 | * ``intersect``, ``minus``, ``union``, ``is_element``, ``is_included``
508 | """
509 | return Pygen(s).eval()
510 |
511 |
512 | #######################################
513 | # A class to adjust giac configuration
514 | #######################################
515 | cdef class GiacSetting(Pygen):
516 | """
517 | A class to customise the Computer Algebra System settings.
518 |
519 | EXAMPLES::
520 |
521 | >>> from sagemath_giac.giac import giacsettings, libgiac
522 |
523 | ``threads`` (maximal number of allowed theads in giac)::
524 |
525 | >>> import os
526 | >>> try:
527 | ... ncpu = int(os.environ['SAGE_NUM_THREADS'])
528 | ... except KeyError:
529 | ... ncpu =1
530 | >>> giacsettings.threads == ncpu
531 | True
532 |
533 | ``digits`` (default digit number used for approximations)::
534 |
535 | >>> giacsettings.digits = 20
536 | >>> libgiac.approx('1/7')
537 | 0.14285714285714285714
538 | >>> giacsettings.digits = 50
539 | >>> libgiac.approx('1/7')
540 | 0.14285714285714285714285714285714285714285714285714
541 | >>> giacsettings.digits = 12
542 |
543 | ``sqrtflag`` (flag to allow sqrt extractions during solve and
544 | factorizations)::
545 |
546 | >>> giacsettings.sqrtflag = False
547 | >>> libgiac('x**2-2').factor()
548 | x^2-2
549 | >>> giacsettings.sqrtflag = True
550 | >>> libgiac('x**2-2').factor()
551 | (x-sqrt(2))*(x+sqrt(2))
552 |
553 | ``complexflag`` (flag to allow complex number in solving equations
554 | or factorizations)::
555 |
556 | >>> giacsettings.complexflag = False; giacsettings.complexflag
557 | False
558 | >>> libgiac('x**2+4').factor()
559 | x^2+4
560 | >>> giacsettings.complexflag = True
561 | >>> libgiac('x**2+4').factor()
562 | (x+2*i)*(x-2*i)
563 |
564 | ``eval_level`` (recursive level of substitution of variables
565 | during an evaluation)::
566 |
567 | >>> giacsettings.eval_level = 1
568 | >>> libgiac("purge(a):;b:=a;a:=1;b")
569 | "Done",a,1,a
570 | >>> giacsettings.eval_level=25; giacsettings.eval_level
571 | 25
572 | >>> libgiac("purge(a):;b:=a;a:=1;b")
573 | "Done",a,1,1
574 |
575 | ``proba_epsilon`` (maximum probability of a wrong answer with a
576 | probabilistic algorithm). Set this number to 0 to disable
577 | probabilistic algorithms (slower)::
578 |
579 | >>> giacsettings.proba_epsilon = 0
580 | >>> libgiac('proba_epsilon')
581 | 0.0
582 | >>> giacsettings.proba_epsilon = 10**(-13)
583 | >>> libgiac('proba_epsilon') < 10**(-14)
584 | False
585 |
586 | ``epsilon`` (value used by the ``epsilon2zero`` function)::
587 |
588 | >>> giacsettings.epsilon = 1e-10
589 | >>> P = libgiac('1e-11+x+5')
590 | >>> P == x+5
591 | False
592 | >>> (P.epsilon2zero()).simplify()
593 | x+5
594 |
595 | """
596 | def __repr__(self):
597 | return "Giac Settings"
598 |
599 | def _sage_doc_(self):
600 | return GiacSetting.__doc__
601 |
602 | property digits:
603 | r"""
604 | Default digits number used for approximations.
605 |
606 | EXAMPLES::
607 |
608 | >>> from sagemath_giac.giac import giacsettings, libgiac
609 | >>> giacsettings.digits = 20
610 | >>> giacsettings.digits
611 | 20
612 | >>> libgiac.approx('1/7')
613 | 0.14285714285714285714
614 | >>> giacsettings.digits=12
615 |
616 | """
617 | def __get__(self):
618 | return (self.cas_setup()[6])._val
619 |
620 | def __set__(self, value):
621 | l = Pygen('cas_setup()').eval()
622 | pl = [ i for i in l ]
623 | pl[6] = value
624 | Pygen('cas_setup(%s)' % pl).eval()
625 |
626 | property sqrtflag:
627 | r"""
628 | Flag to allow square roots in solving equations or
629 | factorizations.
630 | """
631 | def __get__(self):
632 | return (self.cas_setup()[9])._val == 1
633 |
634 | def __set__(self, value):
635 | l = Pygen('cas_setup()').eval()
636 | pl = [ i for i in l ]
637 | if value:
638 | pl[9]=1
639 | else:
640 | pl[9]=0
641 | Pygen('cas_setup(%s)' % pl).eval()
642 |
643 | property complexflag:
644 | r"""
645 | Flag to allow complex number in solving equations or
646 | factorizations.
647 |
648 | EXAMPLES::
649 |
650 | >>> from sagemath_giac.giac import libgiac, giacsettings
651 | >>> giacsettings.complexflag = False
652 | >>> giacsettings.complexflag
653 | False
654 | >>> libgiac('x**2+4').factor()
655 | x^2+4
656 | >>> giacsettings.complexflag=True;
657 | >>> libgiac('x**2+4').factor()
658 | (x+2*i)*(x-2*i)
659 |
660 | """
661 | def __get__(self):
662 | return (self.cas_setup()[2])._val == 1
663 |
664 | def __set__(self, value):
665 | l = Pygen('cas_setup()').eval()
666 | pl = [ i for i in l ]
667 | if value:
668 | pl[2] = 1
669 | else:
670 | pl[2] = 0
671 | Pygen('cas_setup(%s)' % pl).eval()
672 |
673 | property eval_level:
674 | r"""
675 | Recursive level of substitution of variables during an evaluation.
676 |
677 | EXAMPLES::
678 |
679 | >>> from sagemath_giac.giac import giacsettings, libgiac
680 | >>> giacsettings.eval_level=1
681 | >>> libgiac("purge(a):;b:=a;a:=1;b")
682 | "Done",a,1,a
683 | >>> giacsettings.eval_level = 25
684 | >>> giacsettings.eval_level
685 | 25
686 | >>> libgiac("purge(a):;b:=a;a:=1;b")
687 | "Done",a,1,1
688 | >>> libgiac.purge('a,b')
689 | 1,a
690 |
691 | """
692 | def __get__(self):
693 | return (self.cas_setup()[7][3])._val
694 |
695 | def __set__(self, value):
696 | l = Pygen('cas_setup()').eval()
697 | pl = [ i for i in l ]
698 | pl[7] = [l[7][0],l[7][1],l[7][2], value]
699 | Pygen('cas_setup(%s)' % pl).eval()
700 |
701 | property proba_epsilon:
702 | r"""
703 | Maximum probability of a wrong answer with a probabilistic
704 | algorithm.
705 |
706 | Set this number to 0 to disable probabilistic algorithms
707 | (this makes the computation slower).
708 |
709 | EXAMPLES::
710 |
711 | >>> from sagemath_giac.giac import giacsettings,libgiac
712 | >>> giacsettings.proba_epsilon = 0
713 | >>> libgiac('proba_epsilon')
714 | 0.0
715 | >>> giacsettings.proba_epsilon = 10**(-13)
716 | >>> libgiac('proba_epsilon') < 10**(-14)
717 | False
718 |
719 | """
720 | def __get__(self):
721 | return (self.cas_setup()[5][1])._double
722 |
723 | def __set__(self, value):
724 | l = Pygen('cas_setup()').eval()
725 | pl = [ i for i in l ]
726 | pl[5] = [l[5][0],value]
727 | Pygen('cas_setup(%s)' % pl).eval()
728 |
729 | property epsilon:
730 | r"""
731 | Value used by the ``epsilon2zero`` function.
732 |
733 | EXAMPLES::
734 |
735 | >>> from sagemath_giac.giac import giacsettings, libgiac
736 | >>> giacsettings.epsilon = 1e-10
737 | >>> P = libgiac('1e-11+x+5')
738 | >>> P == x+5
739 | False
740 | >>> (P.epsilon2zero()).simplify()
741 | x+5
742 |
743 | """
744 | def __get__(self):
745 | return (self.cas_setup()[5][0])._double
746 |
747 | def __set__(self, value):
748 | l = Pygen('cas_setup()').eval()
749 | pl = [ i for i in l ]
750 | pl[5] = [value,l[5][1]]
751 | Pygen('cas_setup(%s)' % pl).eval()
752 |
753 | property threads:
754 | r"""
755 | Maximal number of allowed theads in giac.
756 | """
757 | def __get__(self):
758 | return (self.cas_setup()[7][0])._val
759 |
760 | def __set__(self, value):
761 | Pygen('threads:=%s' % str(value)).eval()
762 |
763 | ########################################################
764 | # #
765 | # The python class that points to a cpp giac gen #
766 | # #
767 | ########################################################
768 | include 'auto-methods.pxi'
769 |
770 | cdef class Pygen(GiacMethods_base):
771 |
772 | cdef gen * gptr #pointer to the corresponding C++ element of type giac::gen
773 |
774 | def __cinit__(self, s=None):
775 |
776 | #NB: the != here gives problems with the __richcmp__ function
777 | #if (s!=None):
778 | # so it's better to use isinstance
779 | if (isinstance(s, None.__class__)):
780 | # Do NOT replace with: self=GIACNULL (cf the doctest in __repr__
781 | sig_on()
782 | self.gptr = new gen ((GIACNULL).gptr[0])
783 | sig_off()
784 | return
785 |
786 | if isinstance(s, int):
787 | # This looks 100 faster than the str initialisation
788 | if s.bit_length() < Pymaxint.bit_length():
789 | sig_on()
790 | self.gptr = new gen(s)
791 | sig_off()
792 | else:
793 | sig_on()
794 | self.gptr = new gen(pylongtogen(s))
795 | sig_off()
796 |
797 | elif isinstance(s, Integer): # for sage int (gmp)
798 | sig_on()
799 | if (abs(s)>Pymaxint):
800 | self.gptr = new gen((s).value)
801 | else:
802 | self.gptr = new gen(s) # important for pow to have a int
803 | sig_off()
804 |
805 | elif isinstance(s, Rational): # for sage rat (gmp)
806 | #self.gptr = new gen(((Pygen(s.numerator())/Pygen(s.denominator()))).gptr[0])
807 | # FIXME: it's slow
808 | sig_on()
809 | self.gptr = new gen(GIAC_rdiv(gen(((s.numerator())).value),gen(((s.denominator())).value)))
810 | sig_off()
811 |
812 | elif isinstance(s, Matrix):
813 | s = Pygen(s.list()).list2mat(s.ncols())
814 | sig_on()
815 | self.gptr = new gen((s).gptr[0])
816 | sig_off()
817 |
818 | elif isinstance(s, float):
819 | sig_on()
820 | self.gptr = new gen(s)
821 | sig_off()
822 |
823 | elif isinstance(s, Pygen):
824 | # in the test: x,y=Pygen('x,y');((x+2*y).sin()).texpand()
825 | # the y are lost without this case.
826 | sig_on()
827 | self.gptr = new gen((s).gptr[0])
828 | sig_off()
829 |
830 | elif isinstance(s, (list, range)):
831 | sig_on()
832 | self.gptr = new gen(_wrap_pylist(s),0)
833 | sig_off()
834 |
835 | elif isinstance(s, tuple):
836 | sig_on()
837 | self.gptr = new gen(_wrap_pylist(s),1)
838 | sig_off()
839 |
840 | # Other types are converted with strings.
841 | else:
842 | if isinstance(s, Expression):
843 | # take account of conversions with key giac in the sage symbol dict
844 | try:
845 | s = s._giac_init_()
846 | except AttributeError:
847 | s = SRexpressiontoGiac(s)
848 | elif isinstance(s, AnInfinity):
849 | s = s._giac_init_()
850 | if not isinstance(s, str):
851 | s = s.__str__()
852 | sig_on()
853 | self.gptr = new gen(encstring23(s),context_ptr)
854 | sig_off()
855 |
856 | def __dealloc__(self):
857 | del self.gptr
858 |
859 | def __repr__(self):
860 | # fast evaluation of the complexity of the gen. (it's not the number of char )
861 | sig_on()
862 | t=GIAC_taille(self.gptr[0], 6000)
863 | sig_off()
864 | if t < 6000:
865 | sig_on()
866 | result = GIAC_print(self.gptr[0], context_ptr).c_str().decode()
867 | sig_off()
868 | return result
869 | else:
870 | sig_on()
871 | result = str(self.type) + "\nResult is too big for Display. If you really want to see it use print"
872 | sig_off()
873 | return result
874 |
875 | def __str__(self):
876 | #if self.gptr == NULL:
877 | # return ''
878 | sig_on()
879 | result = GIAC_print(self.gptr[0], context_ptr).c_str().decode()
880 | sig_off()
881 | return result
882 |
883 | def __len__(self):
884 | """
885 | TESTS::
886 |
887 | >>> from sagemath_giac.giac import libgiac
888 | >>> l=libgiac("seq[]"); len(l) # 29552 comment28
889 | 0
890 |
891 | """
892 | if (self._type == 7):
893 | sig_on()
894 | rep=(self.gptr.ref_VECTptr()).size()
895 | sig_off()
896 | return rep
897 | else:
898 | sig_on()
899 | rep=GIAC_size(self.gptr[0],context_ptr).val
900 | sig_off()
901 | #GIAC_size return a gen. we take the int: val
902 | return rep
903 |
904 | def __getitem__(self, i): #TODO?: add gen support for indexes
905 | """
906 | Lists of 10**6 integers should be translated to giac easily
907 |
908 | TESTS::
909 |
910 | >>> from sagemath_giac.giac import libgiac
911 | >>> l = libgiac(list(range(10**6))); l[5]
912 | 5
913 | >>> l[35:50:7]
914 | [35,42,49]
915 | >>> l[-10**6]
916 | 0
917 | >>> t = libgiac(tuple(range(10)))
918 | >>> t[:4:-1]
919 | 9,8,7,6,5
920 | >>> x = libgiac('x')
921 | >>> sum([ x[i] for i in range(5) ], libgiac(0))**3
922 | (x[0]+x[1]+x[2]+x[3]+x[4])^3
923 | >>> A = libgiac.ranm(5,10)
924 | >>> A[3,7]-A[3][7]
925 | 0
926 | >>> A.transpose()[8,2]-A[2][8]
927 | 0
928 |
929 | Crash test::
930 |
931 | >>> from sagemath_giac.giac import Pygen
932 | >>> l = Pygen()
933 | >>> l[0]
934 | Traceback (most recent call last):
935 | ...
936 | IndexError: list index 0 out of range
937 |
938 | """
939 | cdef gen result
940 |
941 | if(self._type == 7) or (self._type == 12): #if self is a list or a string
942 | if isinstance(i, (int, Integer)):
943 | n=len(self)
944 | if(ii]
949 | sig_off()
950 | return _wrap_gen(result)
951 | else:
952 | raise IndexError('list index %s out of range' % i)
953 | else:
954 | if isinstance(i, slice):
955 | sig_on()
956 | result = gen(_getgiacslice(self,i),self._subtype)
957 | sig_off()
958 | return _wrap_gen(result)
959 | # add support for multi indexes
960 | elif isinstance(i, tuple):
961 | if(len(i)==2):
962 | return self[i[0]][i[1]]
963 | elif(len(i)==1):
964 | # in case of a tuple like this: (3,)
965 | return self[i[0]]
966 | else:
967 | return self[i[0],i[1]][tuple(i[2:])]
968 | else:
969 | raise TypeError('gen indexes are not yet implemented')
970 | # Here we add support to formal variable indexes:
971 | else:
972 | cmd = '%s[%s]' % (self, i)
973 | ans = Pygen(cmd).eval()
974 | # if the answer is a string, it must be an error message because self is not a list or a string
975 | if (ans._type == 12):
976 | raise TypeError("Error executing code in Giac\nCODE:\n\t%s\nGiac ERROR:\n\t%s" % (cmd, ans))
977 | return ans
978 |
979 | def __setitem__(self, key, value):
980 | """
981 | Set the value of a coefficient of a giac vector or matrix or list.
982 |
983 | Warning: It is an in place affectation.
984 |
985 | TESTS::
986 |
987 | >>> from sagemath_giac.giac import libgiac
988 | >>> from sage.rings.rational_field import QQ
989 | >>> A = libgiac([ [ libgiac(j)+libgiac(i)*2 for i in range(3)] for j in range(3)]); A
990 | [[0,2,4],[1,3,5],[2,4,6]]
991 | >>> A[1,2] = 44; A
992 | [[0,2,4],[1,3,44],[2,4,6]]
993 | >>> A[2][2] = QQ(1)/QQ(3); A
994 | [[0,2,4],[1,3,44],[2,4,1/3]]
995 | >>> x = libgiac('x')
996 | >>> A[0,0] = x + libgiac(1)/x; A
997 | [[x+1/x,2,4],[1,3,44],[2,4,1/3]]
998 | >>> A[0] = [-1,-2,-3]; A
999 | [[-1,-2,-3],[1,3,44],[2,4,1/3]]
1000 | >>> B = A; A[2,2]
1001 | 1/3
1002 | >>> B[2,2] = 6 # in place assignment
1003 | >>> A[2,2] # so A is also modified
1004 | 6
1005 | >>> A.pcar(x)
1006 | x^3-8*x^2-159*x
1007 |
1008 | NB: For Large matrix it seems that the syntax ``A[i][j]=`` is
1009 | faster that ``A[i,j]=``.
1010 | """
1011 | cdef gen v
1012 | sig_on()
1013 | cdef gen g = gen(encstring23('GIACPY_TMP_NAME050268070969290100291003'),context_ptr)
1014 | GIAC_sto((self).gptr[0],g,1,context_ptr)
1015 | g = gen(encstring23('GIACPY_TMP_NAME050268070969290100291003[%s]' % str(key)), context_ptr)
1016 | v=((Pygen(value).eval())).gptr[0]
1017 | GIAC_sto(v, g, 1, context_ptr)
1018 | Pygen('purge(GIACPY_TMP_NAME050268070969290100291003):;').eval()
1019 | sig_off()
1020 | return
1021 |
1022 | def __iter__(self):
1023 | """
1024 | Pygen lists of 10**6 elements should be yield.
1025 |
1026 | TESTS::
1027 |
1028 | >>> from sagemath_giac.giac import libgiac
1029 | >>> l = libgiac(range(10**6))
1030 | >>> [ i for i in l ] == list(range(10**6))
1031 | True
1032 |
1033 | Check for SageMath issue 18841::
1034 |
1035 | >>> L = libgiac(range(10))
1036 | >>> next(iter(L))
1037 | 0
1038 |
1039 | """
1040 | cdef int i
1041 | for i in range(len(self)):
1042 | yield self[i]
1043 |
1044 | def eval(self):
1045 | cdef gen result
1046 | sig_on()
1047 | result = GIAC_protecteval(self.gptr[0],giacsettings.eval_level,context_ptr)
1048 | sig_off()
1049 | return _wrap_gen(result)
1050 |
1051 | def __add__(self, right):
1052 | cdef gen result
1053 | if not isinstance(right, Pygen):
1054 | right=Pygen(right)
1055 | # Curiously this case is important:
1056 | # otherwise: f=1/(2+sin(5*x)) crash
1057 | if not isinstance(self, Pygen):
1058 | self=Pygen(self)
1059 | sig_on()
1060 | result = (self).gptr[0] + (right).gptr[0]
1061 | sig_off()
1062 | return _wrap_gen(result)
1063 |
1064 | def __call__(self, *args):
1065 | cdef gen result
1066 | cdef Pygen pari_unlock = Pygen('pari_unlock()')
1067 | cdef gen pari_unlock_result
1068 | cdef Pygen right
1069 | n = len(args)
1070 | if n > 1:
1071 | # FIXME? improve with a vector, or improve Pygen(list)
1072 | right = Pygen(args).eval()
1073 | elif n == 1:
1074 | right = Pygen(args[0])
1075 | else:
1076 | right = GIACNULL
1077 | if not isinstance(self, Pygen):
1078 | self = Pygen(self)
1079 | # Some giac errors such as pari_locked are caught by the try
1080 | # so we can't put the sig_on() in the try.
1081 | # But now a keyboard interrupt fall back to this sig_on so
1082 | # it may have left the giac pari locked.
1083 | sig_on()
1084 | try:
1085 | result = self.gptr[0](right.gptr[0], context_ptr)
1086 | except RuntimeError:
1087 | # The previous computation might have failed due to a pari_lock
1088 | # So we will not raise an exception yet.
1089 | pari_unlock_result = GIAC_eval(pari_unlock.gptr[0], 1, context_ptr)
1090 | tmp = _wrap_gen(result)
1091 | # if pari was not locked in giac, we have locked it, so unlock it.
1092 | if tmp == 0:
1093 | pari_unlock_result = GIAC_eval(pari_unlock.gptr[0], 1, context_ptr)
1094 | tmp = _wrap_gen(result)
1095 | raise
1096 | else:
1097 | result = GIAC_eval(right.gptr[0], 1, context_ptr)
1098 | result = self.gptr[0](result, context_ptr)
1099 | finally:
1100 | sig_off()
1101 | return _wrap_gen(result)
1102 |
1103 | def __sub__(self, right):
1104 | cdef gen result
1105 | if not isinstance(right, Pygen):
1106 | right=Pygen(right)
1107 | if not isinstance(self, Pygen):
1108 | self=Pygen(self)
1109 | sig_on()
1110 | result = (self).gptr[0] - (right).gptr[0]
1111 | sig_off()
1112 | return _wrap_gen(result)
1113 |
1114 | def __mul__(self, right):
1115 | """
1116 | TESTS::
1117 |
1118 | >>> from sagemath_giac.giac import libgiac
1119 | >>> (libgiac.sqrt(5)*libgiac('x')).factor()
1120 | sqrt(5)*x
1121 | >>> (libgiac('x')*libgiac.sqrt(5)).factor()
1122 | sqrt(5)*x
1123 |
1124 | """
1125 | cdef gen result
1126 | if not isinstance(right, Pygen):
1127 | right = Pygen(right)
1128 | if not isinstance(self, Pygen):
1129 | self = Pygen(self)
1130 | #result = (self).gptr[0] * (right).gptr[0]
1131 | #NB: with the natural previous method, the following error generated by
1132 | #giac causes python to quit instead of an error message.
1133 | #l=Pygen([1,2]);l.transpose()*l;
1134 | sig_on()
1135 | result = GIAC_giacmul((self).gptr[0], (right).gptr[0],context_ptr)
1136 | sig_off()
1137 | return _wrap_gen(result)
1138 |
1139 | # PB / in python3 is truediv
1140 | def __div__(self, right):
1141 | """
1142 | TESTS::
1143 |
1144 | >>> from sagemath_giac.giac import libgiac
1145 | >>> (libgiac.sqrt(3)/libgiac('x')).factor()
1146 | sqrt(3)/x
1147 | >>> (libgiac('x')/libgiac.sqrt(3)).factor()
1148 | sqrt(3)*x/3
1149 |
1150 | """
1151 | cdef gen result
1152 | if not isinstance(right, Pygen):
1153 | right = Pygen(right)
1154 | if not isinstance(self, Pygen):
1155 | self = Pygen(self)
1156 | sig_on()
1157 | result = GIAC_giacdiv((self).gptr[0], (right).gptr[0],context_ptr)
1158 | sig_off()
1159 | return _wrap_gen(result)
1160 |
1161 | def __truediv__(self, right):
1162 | cdef gen result
1163 | if not isinstance(right, Pygen):
1164 | right = Pygen(right)
1165 | if not isinstance(self, Pygen):
1166 | self = Pygen(self)
1167 | sig_on()
1168 | result = (self).gptr[0] / (right).gptr[0]
1169 | sig_off()
1170 | return _wrap_gen(result)
1171 |
1172 | def __pow__(self, right, ignored):
1173 | cdef gen result
1174 | if not isinstance(right, Pygen):
1175 | right = Pygen(right)
1176 | if not isinstance(self, Pygen):
1177 | self = Pygen(self)
1178 | sig_on()
1179 | result = GIAC_pow((self).gptr[0], (right).gptr[0], context_ptr )
1180 | sig_off()
1181 | return _wrap_gen(result)
1182 |
1183 | def __mod__(self, right):
1184 | cdef gen result
1185 | if not isinstance(right, Pygen):
1186 | right = Pygen(right)
1187 | if not isinstance(self, Pygen):
1188 | self = Pygen(self)
1189 | #result = gen(GIAC_makenewvecteur((self).gptr[0],(right).gptr[0]),1)
1190 | #to have an integer output:
1191 | #result = GIAC_smod(result,context_ptr)
1192 | #we give a modular output:
1193 | sig_on()
1194 | result = GIAC_giacmod((self).gptr[0], (right).gptr[0],context_ptr)
1195 | sig_off()
1196 | return _wrap_gen(result)
1197 |
1198 | def __neg__(self):
1199 | cdef gen result
1200 | if not isinstance(self, Pygen):
1201 | self = Pygen(self)
1202 | sig_on()
1203 | result = GIAC_neg((self).gptr[0])
1204 | sig_off()
1205 | return _wrap_gen(result)
1206 |
1207 | def __pos__(self):
1208 | return self
1209 |
1210 | # To be able to use the eval function before the GiacMethods initialisation
1211 | def cas_setup(self, *args):
1212 | return Pygen('cas_setup')(self, *args)
1213 |
1214 | def savegen(self, str filename):
1215 | """
1216 | Archive a Pygen element to a file in giac compressed format.
1217 |
1218 | Use the loadgiacgen command to get back the Pygen from the file.
1219 | In C++ these files can be opened with ``giac::unarchive``.
1220 |
1221 | EXAMPLES::
1222 |
1223 | >>> from sagemath_giac.giac import *
1224 | >>> f = libgiac('(x+y+z+2)**10')
1225 | >>> g = f.normal()
1226 | >>> from tempfile import NamedTemporaryFile
1227 | >>> F = NamedTemporaryFile() # choose a temporary file for a test
1228 | >>> g.savegen(F.name)
1229 | >>> a = loadgiacgen(F.name)
1230 | >>> a.factor()
1231 | (x+y+z+2)^10
1232 | >>> F.close()
1233 |
1234 | """
1235 | sig_on()
1236 | GIAC_archive( encstring23(filename), (self).gptr[0], context_ptr)
1237 | sig_off()
1238 |
1239 |
1240 | def redim(self, a, b=None):
1241 | """
1242 | Increase the size of a matrix when possible, otherwise return ``self``.
1243 |
1244 | EXAMPLES::
1245 |
1246 | >>> from sagemath_giac.giac import libgiac
1247 | >>> C = libgiac([[1,2]])
1248 | >>> C.redim(2,3)
1249 | [[1,2,0],[0,0,0]]
1250 | >>> C.redim(2,1)
1251 | [[1,2]]
1252 |
1253 | """
1254 | d = self.dim()
1255 | if d.type() == 7:
1256 | if(a > d[0] and b >= d[1]):
1257 | a = Pygen(a)
1258 | A = self.semi_augment(Pygen((a-d[0],d[1])).matrix())
1259 | if(b > d[1]):
1260 | b = Pygen(b)
1261 | A = A.augment(Pygen((a,b-d[1])).matrix())
1262 | return A
1263 | elif(b > d[1] and a == d[0]):
1264 | b = Pygen(b)
1265 | return self.augment(Pygen((d[0],b-d[1])).matrix())
1266 | else:
1267 | return self
1268 | else:
1269 | raise TypeError("self is not a giac List")
1270 |
1271 | def _help(self):
1272 | return self.findhelp().__str__()
1273 |
1274 | def _sage_doc_(self):
1275 | return self._help()
1276 |
1277 | def __doc__(self):
1278 | return self._help()
1279 |
1280 | # # # # # # # # # # # # # # # # #
1281 | # sage addons
1282 | # # # # # # # # # # # # # # # # #
1283 | def _latex_(self):
1284 | r"""
1285 | You can output Giac expressions in latex.
1286 |
1287 | EXAMPLES::
1288 |
1289 | >>> from sagemath_giac.giac import libgiac
1290 | >>> from sage.misc.latex import latex
1291 | >>> gf = libgiac('(x^4 - y)/(y^2-3*x)')
1292 | >>> latex(gf)
1293 | \frac{x^{4}-y}{y^{2}-3 x}
1294 |
1295 | """
1296 | sig_on()
1297 | result = GIAC_gen2tex(self.gptr[0], context_ptr).c_str().decode()
1298 | sig_off()
1299 | return result
1300 |
1301 | def _integer_(self, Z=None):
1302 | """
1303 | Convert giac integers or modular integers to sage Integers
1304 | (via gmp).
1305 |
1306 | EXAMPLES::
1307 |
1308 | >>> from sagemath_giac.giac import *
1309 | >>> from sage.arith.misc import next_prime
1310 | >>> from sage.rings.integer_ring import ZZ
1311 | >>> from sage.rings.finite_rings.integer_mod import Mod
1312 | >>> a = libgiac('10')
1313 | >>> b = libgiac('2**300')
1314 | >>> a
1315 | 10
1316 | >>> type(ZZ(a))
1317 |
1318 | >>> next_prime(b)
1319 | 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397533
1320 | >>> c = libgiac('2 % nextprime(2**40)')
1321 | >>> ZZ(c**1000)
1322 | -233775163595
1323 | >>> Mod(2,next_prime(2**40))**1000 - ZZ(c**1000)
1324 | 0
1325 | >>> 2**320-(c**320).sage()
1326 | 0
1327 |
1328 | """
1329 | cdef Integer n = PY_NEW(Integer)
1330 | typ = self._type
1331 |
1332 | if(typ == 0):
1333 | # giac _INT_ i.e int
1334 | return Integer(self._val)
1335 |
1336 | elif(typ == 2):
1337 | # giac _ZINT i.e mpz_t
1338 | sig_on()
1339 | mpz_set(n.value,(self.gptr.ref_ZINTptr())[0])
1340 | sig_off()
1341 | return n
1342 |
1343 | elif(typ == 15):
1344 | # self is a giac modulo
1345 | sig_on()
1346 | a = _wrap_gen( (self.gptr.ref_MODptr())[0])
1347 | # It is useless to get the modulus here
1348 | # because the result will be lift to ZZ.
1349 | result = ZZ(a)
1350 | sig_off()
1351 | return result
1352 |
1353 | else:
1354 | raise TypeError("cannot convert non giac integers to Integer")
1355 |
1356 | def _rational_(self, Z=None):
1357 | """
1358 | Convert giac rationals to sage rationals.
1359 |
1360 | EXAMPLES::
1361 |
1362 | >>> from sagemath_giac.giac import libgiac
1363 | >>> from sage.rings.rational_field import QQ
1364 | >>> a = libgiac('103993/33102')
1365 | >>> b = QQ(a); b
1366 | 103993/33102
1367 | >>> b == a.sage()
1368 | True
1369 |
1370 | """
1371 | typ = self._type
1372 | # _INT_ or _ZINT
1373 | if typ == 0 or typ == 2:
1374 | return QQ(ZZ(self))
1375 | # _FRAC_
1376 | elif typ == 10:
1377 | # giac _RAT_
1378 | return ZZ(self.numer()) / ZZ(self.denom())
1379 | else:
1380 | raise TypeError("cannot convert non giac _FRAC_ to QQ")
1381 |
1382 | def sage(self):
1383 | r"""
1384 | Convert a libgiac expression back to a Sage
1385 | expression. (could be slow)
1386 |
1387 | This currently does not implement a parser for the Giac output
1388 | language, therefore only very simple expressions will convert
1389 | successfully.
1390 |
1391 | Lists are converted recursively to sage.
1392 |
1393 | CURRENT STATUS:
1394 |
1395 | ZZ, QQ, ZZ/nZZ, strings, are supported, other type are sent
1396 | to the symbolic ring via strings. In particular symbolic
1397 | expressions modulo n should be lift to ZZ before (with % 0).
1398 |
1399 | EXAMPLES::
1400 |
1401 | >>> from sagemath_giac.giac import libgiac
1402 | >>> m = libgiac('x^2 + 5*y')
1403 | >>> m.sage()
1404 | x^2 + 5*y
1405 |
1406 | ::
1407 |
1408 | >>> m = libgiac('sin(2*sqrt(1-x^2)) * (1 - cos(1/x))^2')
1409 | >>> m.trigexpand().sage()
1410 | 2*cos(sqrt(-x^2 + 1))*cos(1/x)^2*sin(sqrt(-x^2 + 1)) - 4*cos(sqrt(-x^2 + 1))*cos(1/x)*sin(sqrt(-x^2 + 1)) + 2*cos(sqrt(-x^2 + 1))*sin(sqrt(-x^2 + 1))
1411 |
1412 | ::
1413 |
1414 | >>> a = libgiac(' 2 % 7')
1415 | >>> (a.sage())**6
1416 | 1
1417 | >>> a=libgiac('"une chaine"')
1418 | >>> b=a.sage(); b + b
1419 | 'une chaineune chaine'
1420 | >>> isinstance(b,str)
1421 | True
1422 |
1423 | The giac entries in the pynac conversion dictionary are used::
1424 |
1425 | >>> from sage.symbolic.ring import SR
1426 | >>> x = SR.symbol('x')
1427 | >>> f = libgiac.Gamma
1428 | >>> f(4)
1429 | 6
1430 | >>> f(x)
1431 | Gamma(sageVARx)
1432 | >>> (f(x)).sage()
1433 | gamma(x)
1434 |
1435 | Converting a custom name by adding a new entry to the
1436 | ``symbols_table``::
1437 |
1438 | >>> from sage.symbolic.expression import register_symbol
1439 | >>> from sage.functions.trig import sin
1440 | >>> ex = libgiac('myFun(x)')
1441 | >>> register_symbol(sin, {'giac':'myFun'})
1442 | >>> ex.sage()
1443 | sin(x)
1444 |
1445 | """
1446 | typ = self._type
1447 |
1448 | if typ != 7:
1449 | # self is not a list
1450 | if typ == 0 or typ == 2:
1451 | return ZZ(self)
1452 |
1453 | elif typ == 10:
1454 | return QQ(self)
1455 |
1456 | elif typ == 15:
1457 | # modular integer
1458 | sig_on()
1459 | a = _wrap_gen( (self.gptr.ref_MODptr())[0])
1460 | b = _wrap_gen( (self.gptr.ref_MODptr())[1])
1461 | result = IntegerModRing(ZZ(b))(ZZ(a))
1462 | sig_off()
1463 | return result
1464 |
1465 | elif typ == 12:
1466 | # string
1467 | sig_on()
1468 | result = eval(self.__str__())
1469 | sig_off()
1470 | return result
1471 |
1472 | else:
1473 | return SR(self)
1474 |
1475 | else:
1476 | # self is a list
1477 | sig_on()
1478 | result = [entry.sage() for entry in self]
1479 | sig_off()
1480 | return result
1481 |
1482 | def _symbolic_(self, R):
1483 | r"""
1484 | Convert ``self`` object to the ring R via a basic string evaluation. (slow)
1485 |
1486 | EXAMPLES::
1487 |
1488 | >>> from sagemath_giac.giac import libgiac
1489 | >>> from sage.symbolic.ring import SR
1490 | >>> from sage.functions.trig import sin
1491 | >>> u, v = SR.var('u,v')
1492 | >>> a = libgiac('cos(u+v)').texpand()
1493 | >>> (SR(a)+sin(u)*sin(v)).simplify()
1494 | cos(u)*cos(v)
1495 |
1496 | TESTS:
1497 |
1498 | Check that variables and constants are not mixed up
1499 | (SageMath issue 30133)::
1500 |
1501 | >>> from sage.symbolic.constants import e, I, pi
1502 | >>> ee, ii, pp = SR.var('e,i,pi')
1503 | >>> from sage.functions.trig import cos
1504 | >>> libgiac(ee * ii * pp).sage().variables()
1505 | (e, i, pi)
1506 | >>> libgiac(e * I * pi).sage().variables()
1507 | ()
1508 | >>> libgiac.integrate(ee**x, x).sage()
1509 | e^x/log(e)
1510 | >>> y = SR.var('π')
1511 | >>> libgiac.integrate(cos(y), y).sage()
1512 | sin(π)
1513 |
1514 | """
1515 | if isinstance(R, SR.__class__):
1516 | # Try to convert some functions names to the symbolic ring
1517 | lsymbols = symbol_table['giac'].copy()
1518 | try:
1519 | result = symbolic_expression_from_string(self.__str__(), lsymbols,
1520 | accept_sequence=True,
1521 | parser=SR_parser_giac)
1522 | return result
1523 |
1524 | except Exception:
1525 | raise NotImplementedError("Unable to parse Giac output: %s" % self.__repr__())
1526 | else:
1527 | try:
1528 | result = R(self.__str__())
1529 | return result
1530 |
1531 | except Exception:
1532 | raise NotImplementedError("Unable to parse Giac output: %s" % self.__repr__())
1533 |
1534 | def _matrix_(self, R=ZZ):
1535 | r"""
1536 | Return matrix over the (Sage) ring R where self
1537 | should be a Giac matrix. The default ring is ZZ.
1538 |
1539 | EXAMPLES::
1540 |
1541 | >>> from sagemath_giac.giac import *
1542 | >>> from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1543 | >>> from sage.rings.rational_field import QQ
1544 | >>> from sage.matrix.constructor import matrix
1545 | >>> M = libgiac('matrix(4,4,(k,l)->(x^k-y^l))')
1546 | >>> M
1547 | matrix[[0,1-y,1-y^2,1-y^3],[x-1,x-y,x-y^2,x-y^3],[x^2-1,x^2-y,x^2-y^2,x^2-y^3],[x^3-1,x^3-y,x^3-y^2,x^3-y^3]]
1548 | >>> len(M.eigenvals())
1549 | 4
1550 | >>> R = PolynomialRing(QQ,'x,y')
1551 | >>> Z = matrix(R,M); Z
1552 | [ 0 -y + 1 -y^2 + 1 -y^3 + 1]
1553 | [ x - 1 x - y -y^2 + x -y^3 + x]
1554 | [ x^2 - 1 x^2 - y x^2 - y^2 -y^3 + x^2]
1555 | [ x^3 - 1 x^3 - y x^3 - y^2 x^3 - y^3]
1556 | >>> Z.parent()
1557 | Full MatrixSpace of 4 by 4 dense matrices over Multivariate Polynomial Ring in x, y over Rational Field
1558 |
1559 | """
1560 | cdef int c
1561 | cdef int r
1562 | v = self.dim()
1563 | n = (v[0])._val
1564 | m = (v[1])._val
1565 | from sage.matrix.matrix_space import MatrixSpace
1566 | M = MatrixSpace(R, n, m)
1567 | sig_on()
1568 | entries = [[R((self[r])[c]) for c in range(m)] for r in range(n)]
1569 | sig_off()
1570 | return M(entries)
1571 |
1572 | def _vector_(self, R=None):
1573 | r"""
1574 | Return vector over the (Sage) ring R where self
1575 | should be a Giac matrix. The default ring is ZZ.
1576 |
1577 | EXAMPLES::
1578 |
1579 | >>> from sagemath_giac.giac import libgiac
1580 | >>> from sage.rings.rational_field import QQ
1581 | >>> from sage.modules.free_module_element import vector
1582 | >>> v = libgiac(range(10))
1583 | >>> vector(v+v)
1584 | (0, 2, 4, 6, 8, 10, 12, 14, 16, 18)
1585 | >>> vector(v + v/3, QQ)
1586 | (0, 4/3, 8/3, 4, 16/3, 20/3, 8, 28/3, 32/3, 12)
1587 |
1588 | """
1589 | if isinstance(R, None.__class__):
1590 | R=ZZ
1591 |
1592 | v = self.dim()
1593 | try:
1594 | n = v._val
1595 | except AttributeError:
1596 | raise TypeError("Entry is not a giac vector")
1597 | from sage.modules.free_module_element import vector
1598 | sig_on()
1599 | entries = [R(self[c]) for c in range(n)]
1600 | sig_off()
1601 | return vector(R,entries)
1602 |
1603 | # # # # # # # # # # # # # # #
1604 |
1605 | def mplot(self):
1606 | """
1607 | Basic export of some 2D plots to sage. Only generic plots
1608 | are supported. lines, circles, ... are not implemented
1609 | """
1610 | from sage.plot.line import line
1611 | from sage.plot.scatter_plot import scatter_plot
1612 |
1613 | xyscat = []
1614 | xyplot = []
1615 | plotdata = self
1616 | if not plotdata.type() == 'DOM_LIST':
1617 | plotdata = [plotdata]
1618 |
1619 | sig_on()
1620 | for G in plotdata:
1621 | if G.dim() > 2: # it is not a pnt. Ex: scatterplot
1622 | for g in G:
1623 | xyscat=xyscat+[[(g.real())._double,(g.im())._double]]
1624 |
1625 | else:
1626 | if G[1].type()=='DOM_LIST':
1627 | l=G[1].op()
1628 | else:
1629 | l=G[1][2].op()
1630 | xyplot=[[(u.real())._double,(u.im())._double] for u in l]
1631 |
1632 | if xyscat:
1633 | result = scatter_plot(xyscat)
1634 |
1635 | else:
1636 | result = line(xyplot)
1637 | sig_off()
1638 |
1639 | return result
1640 |
1641 | # # # # # # # # # # # # # # # # # # # # # # # # #
1642 | # WARNING:
1643 | #
1644 | # Do not use things like != in Pygen's __cinit__
1645 | # with this __richcmp__ enabled
1646 | # The methods will bug: a=Pygen(2); a.sin()
1647 | #
1648 | # # # # # # # # # # # # # # # # # # # # # # # # #
1649 |
1650 | def __richcmp__(self, other, op):
1651 | if not isinstance(other, Pygen):
1652 | other = Pygen(other)
1653 | if not isinstance(self, Pygen):
1654 | self = Pygen(self)
1655 | sig_on()
1656 | result = giacgenrichcmp((self).gptr[0],(other).gptr[0], op, context_ptr )
1657 | sig_off()
1658 | return result == 1
1659 |
1660 | #
1661 | # Some attributes of the gen class:
1662 | #
1663 |
1664 | property _type:
1665 | def __get__(self):
1666 | sig_on()
1667 | result = self.gptr.type
1668 | sig_off()
1669 | return result
1670 |
1671 | property _subtype:
1672 | def __get__(self):
1673 | sig_on()
1674 | result = self.gptr.subtype
1675 | sig_off()
1676 | return result
1677 |
1678 | property _val: # immediate int (type _INT_)
1679 | """
1680 | immediate int value of an _INT_ type gen.
1681 | """
1682 | def __get__(self):
1683 | if self._type == 0:
1684 | sig_on()
1685 | result = self.gptr.val
1686 | sig_off()
1687 | return result
1688 | else:
1689 | raise TypeError("cannot convert non _INT_ giac gen")
1690 |
1691 | property _double: # immediate double (type _DOUBLE_)
1692 | """
1693 | immediate conversion to float for a gen of _DOUBLE_ type.
1694 | """
1695 | def __get__(self):
1696 | if self._type == 1:
1697 | sig_on()
1698 | result = self.gptr._DOUBLE_val
1699 | sig_off()
1700 | return result
1701 | else:
1702 | raise TypeError("cannot convert non _DOUBLE_ giac gen")
1703 |
1704 | property help:
1705 | def __get__(self):
1706 | return self._help()
1707 |
1708 | ###################################################
1709 | # Add the others methods
1710 | ###################################################
1711 | #
1712 | # NB: with __getattr__ this is about 10 times slower: [a.normal() for i in range(10**4)]
1713 | # than [GiacMethods["normal"](a) for i in range(10**4)]
1714 | #
1715 | # def __getattr__(self, name):
1716 | # return GiacMethods[str(name)](self)
1717 |
1718 | # test
1719 |
1720 | def giacAiry_Ai(self, *args):
1721 | cdef gen result = GIAC_Airy_Ai(self.gptr[0], context_ptr)
1722 | return _wrap_gen(result)
1723 |
1724 | def giacifactor(self, *args):
1725 | cdef gen result
1726 | sig_on()
1727 | result = GIAC_eval(self.gptr[0], 1, context_ptr)
1728 | result = GIAC_ifactor(result, context_ptr)
1729 | sig_off()
1730 | return _wrap_gen(result)
1731 |
1732 |
1733 | ################################################################
1734 | # A wrapper from a cpp element of type giac gen to create #
1735 | # the Python object #
1736 | ################################################################
1737 | cdef inline _wrap_gen(gen g)except +:
1738 |
1739 | # cdef Pygen pyg=Pygen('NULL')
1740 | # It is much faster with ''
1741 | # [x-x for i in range(10**4)]
1742 | # ('clock: ', 0.010000000000000009,
1743 | # than with 'NULL':
1744 | # [x-x for i in range(10**4)]
1745 | # ('clock: ', 1.1999999999999997,
1746 | # # # # # #
1747 | # This is faster than with:
1748 | # cdef Pygen pyg=Pygen('')
1749 | # ll=giac(range(10**6))
1750 | # ('clock: ', 0.40000000000000036, ' time: ', 0.40346789360046387)
1751 | # gg=[1 for i in ll]
1752 | # ('clock: ', 0.669999999999999, ' time: ', 0.650738000869751)
1753 | #
1754 | # But beware when changing the None case in Pygen init.
1755 | #
1756 | sig_on()
1757 | cdef Pygen pyg=Pygen()
1758 | del pyg.gptr # Pygen.__cinit__() always creates a gen. So we have to delete it here.
1759 | pyg.gptr=new gen(g)
1760 | sig_off()
1761 | return pyg
1762 | # if(pyg.gptr !=NULL):
1763 | # return pyg
1764 | # else:
1765 | # raise MemoryError("empty gen")
1766 |
1767 | ################################################################
1768 | # A wrapper from a python list to a vector of gen #
1769 | ################################################################
1770 |
1771 | cdef vecteur _wrap_pylist(L) except +:
1772 | cdef vecteur * V
1773 | cdef int i
1774 |
1775 | if isinstance(L, (tuple, list, range)):
1776 | n = len(L)
1777 | V = new vecteur()
1778 |
1779 | sig_on()
1780 | for i in range(n):
1781 | V.push_back((Pygen(L[i])).gptr[0])
1782 | sig_off()
1783 | return V[0]
1784 | else:
1785 | raise TypeError("argument must be a tuple or a list")
1786 |
1787 |
1788 | #################################
1789 | # slice wrapper for a giac list
1790 | #################################
1791 | cdef vecteur _getgiacslice(Pygen L, slice sl) except +:
1792 | cdef vecteur * V
1793 | cdef int u
1794 |
1795 | if L.type()=="DOM_LIST":
1796 | n=len(L)
1797 | V=new vecteur()
1798 |
1799 | sig_on()
1800 | # for u in range(n)[sl]: #pb python3
1801 | b, e, st = sl.indices(n)
1802 | for u in range(b, e, st):
1803 | V.push_back((L.gptr[0])[u])
1804 | sig_off()
1805 | return V[0]
1806 | else:
1807 | raise TypeError("argument must be a Pygen list and a slice")
1808 |
1809 |
1810 | cdef gen pylongtogen(a) except +:
1811 | # #
1812 | # basic conversion of Python long integers to gen via Horner's Method #
1813 | # #
1814 |
1815 | aneg=False
1816 | cdef gen g=gen(0)
1817 | cdef gen M
1818 |
1819 | if (a<0):
1820 | aneg=True
1821 | a=-a
1822 | if Pyversioninfo >= (2,7):
1823 | size=a.bit_length() # bit_length python >= 2.7 required.
1824 | shift=Pymaxint.bit_length()-1
1825 | else:
1826 | size=math.trunc(math.log(a,2))+1
1827 | shift=math.trunc(math.log(Pymaxint))
1828 | M=gen((1<=shift):
1831 | size=size-shift
1832 | i=int(a>>size)
1833 | g=(g*M+gen(i))
1834 | a=a-(i<(1< a)
1837 | if aneg:
1838 | # when cythonizing with cython 0.24:
1839 | # g=-g gives an Invalid operand type for '-' (gen)
1840 | g=GIAC_neg(g)
1841 | return g
1842 |
1843 |
1844 | #############################################################
1845 | # Examples of python functions directly implemented from giac
1846 | #############################################################
1847 | #def giaceval(Pygen self):
1848 | # cdef gen result
1849 | # try:
1850 | # result = GIAC_protecteval(self.gptr[0],1,context_ptr)
1851 | # return _wrap_gen(result)
1852 | # except:
1853 | # raise
1854 | #
1855 | #
1856 | #def giacfactor(Pygen self):
1857 | #
1858 | # cdef gen result
1859 | # try:
1860 | # result = GIAC_factor(self.gptr[0],context_ptr)
1861 | # return _wrap_gen(result)
1862 | # except:
1863 | # raise
1864 | #
1865 | #
1866 | #
1867 | #def giacfactors(Pygen self):
1868 | # cdef gen result
1869 | # try:
1870 | # result = GIAC_factors(self.gptr[0],context_ptr)
1871 | # return _wrap_gen(result)
1872 | # except:
1873 | # raise
1874 | #
1875 | #
1876 | #
1877 | #
1878 | #def giacnormal(Pygen self):
1879 | # cdef gen result
1880 | # try:
1881 | # result = GIAC_normal(self.gptr[0],context_ptr)
1882 | # return _wrap_gen(result)
1883 | # except:
1884 | # raise
1885 | #
1886 | #
1887 | #def giacgcd(Pygen a, Pygen b):
1888 | # cdef gen result
1889 | # try:
1890 | # result = gen( GIAC_makenewvecteur(a.gptr[0],b.gptr[0]) ,1)
1891 | # result = GIAC_gcd(result,context_ptr)
1892 | # return _wrap_gen(result)
1893 | # except:
1894 | # raise
1895 |
1896 |
1897 | #############################################################
1898 | # Most giac keywords
1899 | #############################################################
1900 | include 'keywords.pxi'
1901 | GiacMethods={}
1902 |
1903 |
1904 | class GiacFunction(Pygen):
1905 | """
1906 | A Subclass of Pygen to create functions with evaluating all the args
1907 | before call so that they are substituted by their value.
1908 |
1909 | EXAMPLES::
1910 |
1911 | >>> from sagemath_giac.giac import libgiac
1912 | >>> from sage.rings.imaginary_unit import I
1913 | >>> from sage.functions.log import exp
1914 | >>> from sage.symbolic.constants import pi
1915 | >>> libgiac.simplify(exp(I*pi)) # simplify is a GiacFunction
1916 | -1
1917 | >>> libgiac('a:=1')
1918 | 1
1919 | >>> libgiac.purge('a') # purge is not a GiacFunction
1920 | 1
1921 | >>> libgiac('a')
1922 | a
1923 |
1924 | """
1925 | def __call__(self, *args):
1926 | n = len(args)
1927 | if n == 1:
1928 | args = (Pygen(args[0]).eval(),)
1929 | return Pygen.__call__(self, *args)
1930 |
1931 |
1932 | class GiacFunctionNoEV(Pygen):
1933 | # a class to allow to write the __doc__ attribute.
1934 | """
1935 | A Subclass of Pygen to create functions
1936 |
1937 | EXAMPLES::
1938 |
1939 | >>> from sagemath_giac.giac import libgiac
1940 | >>> libgiac('a:=1')
1941 | 1
1942 | >>> libgiac.purge('a') # purge is a GiacFunctionNoEV
1943 | 1
1944 | >>> libgiac('a')
1945 | a
1946 |
1947 | """
1948 |
1949 |
1950 | #############################################################
1951 | # Some convenient settings
1952 | ############################################################
1953 | Pygen('printpow(1)').eval() # default power is ^
1954 | # FIXME: print I for sqrt(-1) instead of i
1955 | # GIAC_try_parse_i(False,context_ptr); (does not work??)
1956 |
1957 | NoEvArgsFunc=['purge','assume','quote']
1958 |
1959 | for i in mostkeywords:
1960 | if i in NoEvArgsFunc:
1961 | # do not eval args before calling this function. Ex purge
1962 | #tmp=Pygen(i)
1963 | tmp = GiacFunctionNoEV(i)
1964 | else:
1965 | tmp = GiacFunction(i)
1966 | # in the sage version we remove: globals()[i]=tmp
1967 | GiacMethods[i] = tmp
1968 |
1969 | # We put the giac names that should not be exported to Python in moremethods.
1970 | for i in moremethods:
1971 | tmp = GiacFunction(i)
1972 | GiacMethods[i] = tmp
1973 |
1974 | for i in mostkeywords+moremethods:
1975 | GiacMethods[i].__doc__ = eval("Pygen." + i + ".__doc__")
1976 |
1977 | # To avoid conflicts we export only these few ones. Most giac keywords will be
1978 | # available through: libgiac.keywordname
1979 | __all__ = ['Pygen', 'giacsettings', 'libgiac', 'loadgiacgen', 'GiacFunction',
1980 | 'GiacMethods', 'GiacMethods_base']
1981 |
1982 |
1983 | def loadgiacgen(str filename):
1984 | """
1985 | Open a file in giac compressed format to create a Pygen element.
1986 |
1987 | Use the save method from Pygen elements to create such files.
1988 |
1989 | In C++ these files can be opened with giac::unarchive and created with
1990 | ``giac::archive``.
1991 |
1992 | EXAMPLES::
1993 |
1994 | >>> from sagemath_giac.giac import *
1995 | >>> g = libgiac.texpand('cos(10*a+5*b)')
1996 | >>> from tempfile import NamedTemporaryFile
1997 | >>> F = NamedTemporaryFile() # choose a temporary file for a test
1998 | >>> g.savegen(F.name)
1999 | >>> a = loadgiacgen(F.name)
2000 | >>> a.tcollect()
2001 | cos(10*a+5*b)
2002 | >>> F.close()
2003 |
2004 | """
2005 | cdef gen result
2006 | sig_on()
2007 | result = GIAC_unarchive( encstring23(filename), context_ptr)
2008 | sig_off()
2009 | return _wrap_gen(result)
2010 |
2011 |
2012 | class GiacInstance:
2013 | """
2014 | This class is used to create the giac interpreter object.
2015 |
2016 | EXAMPLES::
2017 |
2018 | >>> from sagemath_giac.giac import libgiac, GiacInstance
2019 | >>> isinstance(libgiac, GiacInstance)
2020 | True
2021 | >>> libgiac.solve('2*exp(x)<(exp(x*2)-1),x')
2022 | list[x>(ln(sqrt(2)+1))]
2023 |
2024 | """
2025 |
2026 | def __init__(self):
2027 | self.__dict__.update(GiacMethods)
2028 |
2029 | def __call__(self, s):
2030 | return _giac(s)
2031 |
2032 | def _sage_doc_(self):
2033 | return _giac.__doc__
2034 |
2035 | def eval(self, code, strip=True, **kwds):
2036 |
2037 | if strip:
2038 | code = code.replace("\n","").strip()
2039 | return self(code)
2040 |
2041 | __doc__ = _giac.__doc__
2042 |
2043 |
2044 | libgiac = GiacInstance()
2045 |
2046 | # Issue #23976 (bound threads with SAGE_NUM_THREADS)
2047 | import os
2048 | try:
2049 | ncpus = int(os.environ['SAGE_NUM_THREADS'])
2050 | except KeyError:
2051 | ncpus = 1
2052 |
2053 | giacsettings.threads = ncpus
2054 |
--------------------------------------------------------------------------------