├── .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 | --------------------------------------------------------------------------------