You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(9) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(1) |
Feb
|
Mar
(11) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(9) |
Sep
|
Oct
|
Nov
|
Dec
(5) |
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(21) |
Dec
|
2006 |
Jan
|
Feb
(6) |
Mar
(1) |
Apr
(8) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2007 |
Jan
|
Feb
(6) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Alex M. <al...@us...> - 2003-08-08 11:29:45
|
Update of /cvsroot/gmpy/gmpy In directory sc8-pr-cvs1:/tmp/cvs-serv4795 Added Files: README Log Message: Ensure smooth testing on Win32 --- NEW FILE: README --- General MultiPrecision arithmetic for Python -- i.e., Python 2.3 interface module for library GMP 4 -- release 1.0 alpha (August 2003) Detailed documentation in subdirectory doc. To install GMPY 1.0 from sources (you need to have Python 2.3 and GMP 4 previously installed): at a shell prompt, python setup.py install Note that, on Windows, you may use the distributed binary release rather than having to rebuid from sources; to build from sources, you need a Windows installation of GMP 4 (ftp://ftp.whiterose.net/pub/lundman/). To test your installation: cd test, then python gmpy_test.py For any support request, mail Alex Martelli, al...@ya... |
From: Alex M. <al...@us...> - 2003-08-08 09:49:00
|
Update of /cvsroot/gmpy/gmpy/src In directory sc8-pr-cvs1:/tmp/cvs-serv23341/src Modified Files: gmpy.c Log Message: better diagnosis of some cases of wrong # of arguments being passed. Index: gmpy.c =================================================================== RCS file: /cvsroot/gmpy/gmpy/src/gmpy.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** gmpy.c 8 Aug 2003 08:57:05 -0000 1.6 --- gmpy.c 8 Aug 2003 09:48:57 -0000 1.7 *************** *** 104,107 **** --- 104,109 ---- * 1.0: * minor cleanups, ensure support for Python 2.3 + * fixed misdiagnosis of some argument couns in macro + * SELF_ONE_ARG_CONVERTED (tx to Paul Rubin!) * */ *************** *** 313,320 **** #define SELF_ONE_ARG_CONVERTED(nm, converter, var) \ if(self) { \ ! if(args && !PyArg_ParseTuple(args, "|O&", converter, var)) \ return last_try_self(nm, 1, 1, args, self); \ Py_INCREF(self); \ } else { \ if(!PyArg_ParseTuple(args, "O&|O&", converter,&self, converter,var)) \ return last_try(nm, 1, 2, args); \ --- 315,331 ---- #define SELF_ONE_ARG_CONVERTED(nm, converter, var) \ if(self) { \ ! if(args && !PyArg_ParseTuple(args, "O&", converter, var)) \ return last_try_self(nm, 1, 1, args, self); \ Py_INCREF(self); \ } else { \ + if(!PyArg_ParseTuple(args, "O&O&", converter,&self, converter,var)) \ + return last_try(nm, 2, 2, args); \ + } + #define SELF_ONE_ARG_CONVERTED_OPT(nm, converter, var) \ + if(self) { \ + if(args && !PyArg_ParseTuple(args, "|O&", converter, var)) \ + return last_try_self(nm, 0, 1, args, self); \ + Py_INCREF(self); \ + } else { \ if(!PyArg_ParseTuple(args, "O&|O&", converter,&self, converter,var)) \ return last_try(nm, 1, 2, args); \ *************** *** 2918,2922 **** fprintf(stderr, "Pympf_f2q: %p, %p\n", self, args); ! SELF_ONE_ARG_CONVERTED("f2q", Pympf_convert_arg,&err); assert(Pympf_Check(self)); fself = (PympfObject*)self; --- 2929,2933 ---- fprintf(stderr, "Pympf_f2q: %p, %p\n", self, args); ! SELF_ONE_ARG_CONVERTED_OPT("f2q", Pympf_convert_arg, &err); assert(Pympf_Check(self)); fself = (PympfObject*)self; *************** *** 4607,4611 **** int multiplicity; ! SELF_ONE_ARG_CONVERTED("remove",Pympz_convert_arg, &factor); assert(Pympz_Check(self)); assert(Pympz_Check(factor)); --- 4618,4622 ---- int multiplicity; ! SELF_ONE_ARG_CONVERTED("remove", Pympz_convert_arg, &factor); assert(Pympz_Check(self)); assert(Pympz_Check(factor)); *************** *** 4816,4820 **** PyObject* res; ! SELF_ONE_ARG_CONVERTED("jacobi", Pympz_convert_arg,&other); assert(Pympz_Check(self)); assert(Pympz_Check(other)); --- 4827,4831 ---- PyObject* res; ! SELF_ONE_ARG_CONVERTED("jacobi", Pympz_convert_arg, &other); assert(Pympz_Check(self)); assert(Pympz_Check(other)); *************** *** 4848,4852 **** PyObject* res; ! SELF_ONE_ARG_CONVERTED("legendre", Pympz_convert_arg,&other); assert(Pympz_Check(self)); assert(Pympz_Check(other)); --- 4859,4863 ---- PyObject* res; ! SELF_ONE_ARG_CONVERTED("legendre", Pympz_convert_arg, &other); assert(Pympz_Check(self)); assert(Pympz_Check(other)); *************** *** 4882,4886 **** int ires; ! SELF_ONE_ARG_CONVERTED("kronecker", Pympz_convert_arg,&other); assert(Pympz_Check(self)); assert(Pympz_Check(other)); --- 4893,4897 ---- int ires; ! SELF_ONE_ARG_CONVERTED("kronecker", Pympz_convert_arg, &other); assert(Pympz_Check(self)); assert(Pympz_Check(other)); *************** *** 4993,4997 **** PyObject *res; ! SELF_ONE_ARG_CONVERTED("reldiff", Pympf_convert_arg,&op); assert(Pympf_Check(self)); --- 5004,5008 ---- PyObject *res; ! SELF_ONE_ARG_CONVERTED("reldiff", Pympf_convert_arg, &op); assert(Pympf_Check(self)); |
From: Alex M. <al...@us...> - 2003-08-08 09:49:00
|
Update of /cvsroot/gmpy/gmpy/test In directory sc8-pr-cvs1:/tmp/cvs-serv23341/test Modified Files: gmpy_test_mpf.py gmpy_test_mpz.py Log Message: better diagnosis of some cases of wrong # of arguments being passed. Index: gmpy_test_mpf.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/test/gmpy_test_mpf.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** gmpy_test_mpf.py 8 Aug 2003 08:57:05 -0000 1.1 --- gmpy_test_mpf.py 8 Aug 2003 09:48:57 -0000 1.2 *************** *** 97,100 **** --- 97,115 ---- >>> (b**2).reldiff(b*b) < (2.0**-(b.getprec()-1)) 1 + >>> _g.reldiff(3.4) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.reldiff(3.4) + TypeError: function takes exactly 2 arguments (1 given) + >>> a.reldiff() + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.reldiff() + TypeError: function takes exactly 1 argument (0 given) + >>> a.reldiff(3, 4) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.reldiff(3, 4) + TypeError: function takes exactly 1 argument (2 given) >>> a.sqrt() mpf('1.11110755554986664846e1') Index: gmpy_test_mpz.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/test/gmpy_test_mpz.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** gmpy_test_mpz.py 8 Aug 2003 08:57:05 -0000 1.1 --- gmpy_test_mpz.py 8 Aug 2003 09:48:57 -0000 1.2 *************** *** 172,175 **** --- 172,190 ---- >>> a.hamdist(b) 6 + >>> _g.hamdist(3) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.hamdist(3) + TypeError: function takes exactly 2 arguments (1 given) + >>> a.hamdist() + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.hamdist() + TypeError: function takes exactly 1 argument (0 given) + >>> a.hamdist(3, 4) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.hamdist(3, 4) + TypeError: function takes exactly 1 argument (2 given) >>> a.lowbits(5) mpz(27) *************** *** 372,375 **** --- 387,405 ---- >>> b.invert(100) mpz(0) + >>> _g.invert(3) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.invert(3) + TypeError: function takes exactly 2 arguments (1 given) + >>> a.invert() + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.invert() + TypeError: function takes exactly 1 argument (0 given) + >>> a.invert(3, 4) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.invert(3, 4) + TypeError: function takes exactly 1 argument (2 given) >>> _g.comb(3,-1) Traceback (most recent call last): *************** *** 388,391 **** --- 418,436 ---- File "<stdin>", line 1, in ? ValueError: factor must be > 0 + >>> _g.remove(3) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.remove(3) + TypeError: function takes exactly 2 arguments (1 given) + >>> a.remove() + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.remove() + TypeError: function takes exactly 1 argument (0 given) + >>> a.remove(3, 4) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.remove(3, 4) + TypeError: function takes exactly 1 argument (2 given) >>> _g.is_prime(3,-3) Traceback (most recent call last): *************** *** 398,401 **** --- 443,461 ---- File "<stdin>", line 1, in ? ValueError: jacobi's y must be odd prime > 0 + >>> _g.jacobi(3) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.jacobi(3) + TypeError: function takes exactly 2 arguments (1 given) + >>> a.jacobi() + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.jacobi() + TypeError: function takes exactly 1 argument (0 given) + >>> a.jacobi(3, 4) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.jacobi(3, 4) + TypeError: function takes exactly 1 argument (2 given) >>> _g.legendre(10,3) 1 *************** *** 404,411 **** --- 464,501 ---- File "<stdin>", line 1, in ? ValueError: legendres's y must be odd and > 0 + >>> _g.legendre(3) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.legendre(3) + TypeError: function takes exactly 2 arguments (1 given) + >>> a.legendre() + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.legendre() + TypeError: function takes exactly 1 argument (0 given) + >>> a.legendre(3, 4) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.legendre(3, 4) + TypeError: function takes exactly 1 argument (2 given) >>> _g.kronecker(10,3) 1 >>> _g.kronecker(10,-3) 1 + >>> _g.kronecker(3) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + _g.kronecker(3) + TypeError: function takes exactly 2 arguments (1 given) + >>> a.kronecker() + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.kronecker() + TypeError: function takes exactly 1 argument (0 given) + >>> a.kronecker(3, 4) + Traceback (innermost last): + File "<pyshell#184>", line 1, in ? + a.kronecker(3, 4) + TypeError: function takes exactly 1 argument (2 given) >>> a=1000000L**2 >>> b=a+1 |
From: Alex M. <al...@us...> - 2003-08-08 09:49:00
|
Update of /cvsroot/gmpy/gmpy/doc In directory sc8-pr-cvs1:/tmp/cvs-serv23341/doc Modified Files: index.html Log Message: better diagnosis of some cases of wrong # of arguments being passed. Index: index.html =================================================================== RCS file: /cvsroot/gmpy/gmpy/doc/index.html,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** index.html 8 Aug 2003 09:15:57 -0000 1.4 --- index.html 8 Aug 2003 09:48:57 -0000 1.5 *************** *** 149,153 **** formatting functionality. <p> ! Unit tests are not considered a weak point any more; the almost-1000 unit-tests now being run provide a decent cover of 93+% SLOC for gmpy.c, up from 72% in 0.7. The non-covered SLOCs (about 170 of gmpy.c's --- 149,153 ---- formatting functionality. <p> ! Unit tests are not considered a weak point any more; the over 1000 unit-tests now being run provide a decent cover of 93+% SLOC for gmpy.c, up from 72% in 0.7. The non-covered SLOCs (about 170 of gmpy.c's |
From: Alex M. <al...@us...> - 2003-08-08 09:16:02
|
Update of /cvsroot/gmpy/gmpy/doc In directory sc8-pr-cvs1:/tmp/cvs-serv18786 Modified Files: gmpydoc.txt index.html Log Message: Minor changes for 1.0. Index: gmpydoc.txt =================================================================== RCS file: /cvsroot/gmpy/gmpy/doc/gmpydoc.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** gmpydoc.txt 5 Mar 2002 11:05:11 -0000 1.3 --- gmpydoc.txt 8 Aug 2003 09:15:57 -0000 1.4 *************** *** 36,39 **** --- 36,41 ---- Minor editing for version 0.9c (2002/03/05). + Minor editing for version 1.0 (2003/08/08). + *Acknowledgments* *************** *** 55,68 **** *Installation and testing* ! Pre-requisites: Python 2.2, GMP 4.0.1 (see later for Win32). GMP 3.1.1 is still supported for the moment (but will be phased out soon) -- testing and bugfixes only for bugs reproducible in GMP 4 (no more workarounds for GMP 3 - only bugs). Not yet any GMP 4 only functionality. ! No known use of Python 2.2-only functionality yet, but no support/bugfixes planned for older Python releases. To build gmpy from sources, unpack the sources zipfile ! (gmpy-sources-09.zip, for example, for release 0.9) into a new, dedicated directory; cd to that directory (from any shell on Unix/Linux, from a 'Dos box' aka --- 57,70 ---- *Installation and testing* ! Pre-requisites: Python 2.3, GMP 4.0.1 (see later for Win32). GMP 3.1.1 is still supported for the moment (but will be phased out soon) -- testing and bugfixes only for bugs reproducible in GMP 4 (no more workarounds for GMP 3 - only bugs). Not yet any GMP 4 only functionality. ! No known use of Python 2.3-only functionality yet, but no support/bugfixes planned for older Python releases. To build gmpy from sources, unpack the sources zipfile ! (gmpy-sources-10.zip, for example, for release 1.0) into a new, dedicated directory; cd to that directory (from any shell on Unix/Linux, from a 'Dos box' aka *************** *** 78,82 **** be used (the linker will give two warnings, but they are innocuous ones -- please ignore them). GMP 3.1.1 for MSVC++ ! 6 is found at: ftp://ftp.whiterose.net/pub/lundman. GMP 4 for Windows has not been checked out yet. Take care --- 80,85 ---- be used (the linker will give two warnings, but they are innocuous ones -- please ignore them). GMP 3.1.1 for MSVC++ ! 6 is found at: ftp://ftp.whiterose.net/pub/lundman -- but ! you don't need to download that to build and use gmpy. GMP 4 for Windows has not been checked out yet. Take care *************** *** 89,100 **** Distutils are not yet supported for the pre-built gmpy.pyd ! for windows, that comes in the gmpy-win32-binary-08.zip ! file -- just move the gmpy.pyd it contains to c:\Python22 ! (or wherever you have your Python 2.2 installation). The sources zipfile also contains this file (gmpydoc.txt), an example C source file for a separate module that uses the C-API of gmpy to interoperate with it (the .pyd for ! that example module, for Win32, is also in -binary-08.zip), a copy of the index.html for the gmpy sourceforge site, and python scripts that exemplify, show the performance --- 92,103 ---- Distutils are not yet supported for the pre-built gmpy.pyd ! for windows, that comes in the gmpy-win32-binary-10.zip ! file -- just move the gmpy.pyd it contains to c:\Python23 ! (or wherever you have your Python 2.3 installation). The sources zipfile also contains this file (gmpydoc.txt), an example C source file for a separate module that uses the C-API of gmpy to interoperate with it (the .pyd for ! that example module, for Win32, is also in -binary-10.zip), a copy of the index.html for the gmpy sourceforge site, and python scripts that exemplify, show the performance *************** *** 103,126 **** To test the installation, ensure Tim Peter's doctest.py ! is in a directory in the PYTHONPATH (a copy is enclosed ! in the gmpy sources zipfile), and, in the directory where you unpacked the sources, run at the command prompt: ! python gmpy_test_09.py Expected output is something like (details may differ!): """ ! Unit tests for gmpy 0.9 pre-alpha ! on Python 2.2 (#1, Dec 23 2001, 20:09:01) ! [GCC 2.96 20000731 (Mandrake Linux 8.1 2.96-0.62mdk)] ! Testing gmpy 0.9.0c (GMP 4.0.1), default caching (20, 20, -2..11) ! gmpy_test_09_cvr 262 tests, 0 failures ! gmpy_test_09_rnd 26 tests, 0 failures ! gmpy_test_09_mpf 140 tests, 0 failures ! gmpy_test_09_mpq 242 tests, 0 failures ! gmpy_test_09_mpz 310 tests, 0 failures 25 items passed all tests: ! [ 25 lines snipped ] ! 980 tests in 25 items. 980 passed and 0 failed. Test passed. --- 106,132 ---- To test the installation, ensure Tim Peter's doctest.py ! is in a directory in the PYTHONPATH (it's in the standard ! library since 2.1, so, no problem:-), and, in the directory where you unpacked the sources, run at the command prompt: ! python gmpy_test.py Expected output is something like (details may differ!): """ ! Unit tests for gmpy 1,0 alpha ! on Python 2.3+ (#1, Aug 5 2003, 17:15:06) ! [GCC 3.2.2 (Mandrake Linux 9.1 3.2.2-3mdk)] ! Testing gmpy 1.0 (GMP 4.0.1), default caching (20, 20, -2..11) ! gmpy_test_cvr 262 tests, 0 failures ! gmpy_test_rnd 26 tests, 0 failures ! gmpy_test_mpf 140 tests, 0 failures ! gmpy_test_mpq 242 tests, 0 failures ! gmpy_test_mpz 310 tests, 0 failures ! 5 items had no tests: ! gmpy_test_cvr._test ! [[ snip snip ]] 25 items passed all tests: ! [[ snip snip ]] ! 980 tests in 30 items. 980 passed and 0 failed. Test passed. *************** *** 130,135 **** that each of the various modules listed at the start can also be run independently, if so desired: ! python gmpy_test_09_mpq.py ! python gmpy_test_09_mpz.py and so on, expecting output analogous to the above example. The key issue is the 'Test passed' line at the end of each run! --- 136,141 ---- that each of the various modules listed at the start can also be run independently, if so desired: ! python gmpy_test_mpq.py ! python gmpy_test_mpz.py and so on, expecting output analogous to the above example. The key issue is the 'Test passed' line at the end of each run! *************** *** 137,141 **** *PLEASE* report any failures to gmpy's maintainers, with any details you can supply on your machine, on your OS, and ! on your installation of GMP 4, gmpy 0.9, Python 2.2, and any other relevant issue (your C/C++ compiler & libraries, &c). *THANKS* in advance -- bug reporting and feedback is your --- 143,147 ---- *PLEASE* report any failures to gmpy's maintainers, with any details you can supply on your machine, on your OS, and ! on your installation of GMP 4, gmpy 1.0, Python 2.3, and any other relevant issue (your C/C++ compiler & libraries, &c). *THANKS* in advance -- bug reporting and feedback is your Index: index.html =================================================================== RCS file: /cvsroot/gmpy/gmpy/doc/index.html,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** index.html 5 Mar 2002 11:05:11 -0000 1.3 --- index.html 8 Aug 2003 09:15:57 -0000 1.4 *************** *** 14,19 **** <BODY> <FONT SIZE=-1> ! Last updated on: 2002, Mar 5; ! for GMPY release: 0.9.0c pre-alpha <A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=13335&type=1" --- 14,19 ---- <BODY> <FONT SIZE=-1> ! Last updated on: 2003, Aug 8; ! for GMPY release: 1.0 alpha <A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=13335&type=1" *************** *** 48,52 **** exposure of MPZ, MPF (floating-point), and MPQ (rational) functionality of current GMP (release 4.0), that will fully ! support current Python (release 2.2) and its handy 'distutils' (and also support a "C API" allowing some level of interoperation with other C-written extension modules for Python). --- 48,52 ---- exposure of MPZ, MPF (floating-point), and MPQ (rational) functionality of current GMP (release 4.0), that will fully ! support current Python (release 2.3) and its handy 'distutils' (and also support a "C API" allowing some level of interoperation with other C-written extension modules for Python). *************** *** 66,75 **** the same module, or as a further, separate add-on module). Rooting for MPFR to be merged with GMP so we can avoid some ! awkwardness (hopefully by GMP 4.1 later in Spring 2002...!). <H2>Mutability... but <u>not</u> for now</H2> Early tests have shown that supporting Python 2's "in-place operation" functionality (by making MPZ, MPF and MPQ Python objects ! <b>mutable</b>) could offer a substantial performance boost. <p> Despite this, widespread feeling among Python cognoscenti appears --- 66,75 ---- the same module, or as a further, separate add-on module). Rooting for MPFR to be merged with GMP so we can avoid some ! awkwardness (but seeing no movement on this front so far). <H2>Mutability... but <u>not</u> for now</H2> Early tests have shown that supporting Python 2's "in-place operation" functionality (by making MPZ, MPF and MPQ Python objects ! <b>mutable</b>) would offer a substantial performance boost. <p> Despite this, widespread feeling among Python cognoscenti appears *************** *** 90,101 **** <H1>Project Status and near-future plans</H1> ! The gmpy module's early, pre-alpha releases (latest current release ! as of 2002/03/05: 0.9.0c) are available for download in both ! source and Windows-binary form. They expose all of the mpz, mpq and mpf functionality that was already available in GMP 3.1, and most of the random-number generation functionality (there are no current plans to extend gmpy to expose other such functionality, ! although the currently experimental way that it is architected is ! subject to likely future changes). <p> On most platforms, you will need to separately procure and install --- 90,101 ---- <H1>Project Status and near-future plans</H1> ! The gmpy module's alpha release (latest current release ! as of 2002/08/08: 1.0) is available for download in both ! source and Windows-binary form. It exposes all of the mpz, mpq and mpf functionality that was already available in GMP 3.1, and most of the random-number generation functionality (there are no current plans to extend gmpy to expose other such functionality, ! although the currently experimental way in which it is architected ! is subject to possible future changes). <p> On most platforms, you will need to separately procure and install *************** *** 164,168 **** use, and also in the context of PySymbolic, a tad too many design decisions have been delayed/postponed by introducing module-level ! flags, letting us 'have it both ways' in the current pre-alpha gmpy; this has produced a somewhat unwieldy mix of module-level flag-setting and call-back functions. This whole area's architecture --- 164,168 ---- use, and also in the context of PySymbolic, a tad too many design decisions have been delayed/postponed by introducing module-level ! flags, letting us 'have it both ways' in the current alpha gmpy; this has produced a somewhat unwieldy mix of module-level flag-setting and call-back functions. This whole area's architecture *************** *** 170,190 **** <H2>Near-future plans</h2> ! The first alpha release, 1.0, is not deemed to ! be very far at this time. It will only differ ! in degree, not in kind, from the current pre-alphas. ! <p> ! Main changes foreseen will include: re-architecting ! the module-level setting functions; more elegantly ! formatted documentation; more timing-measurement ! scripts and usage-examples. Some of the currently ! experimental 'callbacks' will also be removed, ! having been proven unnecessary. All relevant GMP 4 ! functionality will be exposed. <p> ! The current plans forecast all of this will be completed ! on, or before, May 1, 2002 (give or take about 10 days). ! But our predictions have proved optimistic in the past, ! so, don't hold your breath (pitching in and helping it ! happen, on the other hand, _might_ be advisable:-). <p> <A HREF="http://sourceforge.net/projects/gmpy/">Project --- 170,183 ---- <H2>Near-future plans</h2> ! Future releases may have changes including: re-architecting the ! module-level setting functions; more elegantly formatted documentation; ! more timing-measurement scripts and usage-examples. Some of the ! currently experimental 'callbacks' will also be removed, having been ! proven unnecessary. All relevant GMP 4 functionality will be exposed. <p> ! No predictions on timing, though. gmpy 1.0 meets all current needs ! of the main author, so his motivation to work more on it is low:-). ! So, don't hold your breath (pitching in and helping it happen, on the ! other hand, _might_ be advisable:-). <p> <A HREF="http://sourceforge.net/projects/gmpy/">Project |
Update of /cvsroot/gmpy/gmpy/test In directory sc8-pr-cvs1:/tmp/cvs-serv15488/test Modified Files: timing1.py timing2.py timing3.py Added Files: gmpy_test.py gmpy_test_cvr.py gmpy_test_mpf.py gmpy_test_mpq.py gmpy_test_mpz.py gmpy_test_rnd.py Removed Files: doctest.py gmpy_test_08.py gmpy_test_08_cvr.py gmpy_test_08_mpf.py gmpy_test_08_mpq.py gmpy_test_08_mpz.py gmpy_test_08_rnd.py gmpy_test_09.py gmpy_test_09_cvr.py gmpy_test_09_mpf.py gmpy_test_09_mpq.py gmpy_test_09_mpz.py gmpy_test_09_rnd.py Log Message: Minor updates for 1.0 alpha (supporting Python 2.3) --- NEW FILE: gmpy_test.py --- r''' >>> gmpy.version() '1.0' >>> ''' import sys import doctest import gmpy if sys.argv[-1] == 'debug': gmpy.set_debug(1) import gmpy_test_cvr import gmpy_test_rnd import gmpy_test_mpf import gmpy_test_mpq import gmpy_test_mpz test_modules = (gmpy_test_cvr, gmpy_test_rnd, gmpy_test_mpf, gmpy_test_mpq, gmpy_test_mpz ) _g = gmpy print "Unit tests for gmpy 1,0 alpha" print " on Python",sys.version print "Testing gmpy %s (GMP %s), default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) pf, pt = 0, 0 for x in test_modules: print x.__name__, failures, tests = x._test() print "%3d tests, %d failures" % (tests-pt, failures-pf) pf, pt = failures, tests doctest.master.summarize(1) --- NEW FILE: gmpy_test_cvr.py --- # partial unit test for gmpy 1.0 extra cover # relies on Tim Peters' "doctest.py" test-driver # test-version 1.0 r''' >>> _g.gmp_version() '4.0.1' >>> _g.version() '1.0' ''' import gmpy as _g, doctest, sys __test__={} r = _g.rand __test__['misc_stuff']=\ r''' >>> junk=_g.set_debug(0) >>> knuj=_g.set_debug(junk) >>> junk==_g.set_debug(junk) 1 >>> _g.set_fcoform(None) >>> _g.set_fcoform() >>> print _g.mpf(3.0) 3.0 >>> ''' __test__['user_errors']=\ r''' >>> _g.version(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.gmp_version(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.get_zcache(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_zcache(2000) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_zcache(-23) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.get_qcache(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_qcache(2000) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_qcache(-42) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.get_zconst(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_zconst() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (0 given) >>> _g.set_zconst(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (1 given) >>> _g.set_zconst(23,45,67) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (3 given) >>> _g.set_zconst(23,'blub') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.set_zconst(-1000,1000) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_zconst(100,-100) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_debug() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 1 argument (0 given) >>> _g.set_debug(2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 1 argument (2 given) >>> _g.set_debug('boh') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.set_minprec(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: minimum precision must be >= 0 >>> _g.set_fcoform(33) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: number of digits n must be 0<n<=30 >>> _g.set_fcoform([]) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: set_fcoform argument must be int, string, or None >>> _g.mpz('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpf('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpq('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpq('bo',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (too short) >>> _g.mpq('bologna',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (num len) >>> _g.mpq('\001\000\000\000\003\002',256) mpq(3,2) >>> _g.mpq('\002\000\000\000\003\377\002',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (num sgn) >>> _g.mpq('\001\000\000\000\003\002\377',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (den sgn) >>> _g.mpq('ba/bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> print 'ba/bo' ba/bo >>> _g.mpq('1/bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> print '1/bo' 1/bo >>> _g.mpq('1/0') Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq: zero denominator >>> _g.mpf([]) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() expects numeric or string argument >>> _g.mpf('bo',0,256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string too short to be a gmpy.mpf binary encoding >>> _g.mpf('bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> int(_g.mpz(1000*1000*1000*1000L)) Traceback (most recent call last): File "<stdin>", line 1, in ? OverflowError: mpz too large for int >>> _g.scan0(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: starting bit must be >= 0 >>> _g.scan1(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: starting bit must be >= 0 >>> _g.lowbits(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: nbits must be > 0 >>> _g.getbit(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bit_index must be >= 0 >>> _g.setbit(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bit_index must be >= 0 >>> _g.mpz(23).setbit(12,1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 2 arguments (4 given) >>> _g.setbit(12,1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 3 arguments (4 given) >>> _g.root(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be > 0 >>> _g.root(12,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be > 0 >>> _g.root(-12,2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: root of negative number >>> _g.digits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.fdigits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.qdigits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.mpz(3).digits('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.mpf(3).digits('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.qdiv(3,_g.mpq(1)) mpz(3) >>> _g.qdiv(3,_g.mpz(1)) mpz(3) >>> _g.qdiv(3,_g.mpf(1)) mpz(3) >>> _g.qdiv(3,1.0) mpz(3) >>> _g.qdiv(3,1L) mpz(3) >>> _g.qdiv(3) mpz(3) >>> _g.qdiv(3,'bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: second argument to qdiv not a number >>> _g.mpq(2).qdiv(3,4) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 1 argument (2 given) >>> _g.qdiv(3,4,5) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 2 arguments (3 given) >>> _g.qdiv('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: first argument to qdiv not a number >>> _g.qdiv(1.0,1) mpz(1) >>> _g.qdiv(1.0,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: qdiv: zero divisor >>> _g.f2q(-1.0) mpz(-1) >>> _g.mpz(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() requires 1 or 2 arguments >>> _g.mpz('bi','bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz(): base must be an integer >>> _g.mpz('bi',99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpz must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpz(1,2) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() with numeric argument needs exactly 1 argument >>> _g.mpz(None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() expects numeric or string argument >>> _g.mpq(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq() requires 1 or 2 arguments >>> _g.mpq('bi','bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq(): base must be an integer >>> _g.mpq('bi',99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpq() must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpq(None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq() expects numeric or string argument >>> _g.mpq(1,None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpq >>> _g.mpq(1,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq: zero denominator >>> _g.mpf() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() requires 1 to 3 arguments >>> _g.mpf(1,'bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf(): bits must be an integer >>> _g.mpf(1,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bits for gmpy.mpf must be >= 0 >>> _g.mpf('ba',0,'bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf(): base must be an integer >>> _g.mpf('ba',0,99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpf must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpf(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() with numeric 1st argument needs 1 or 2 arguments >>> +_g.mpz(1) mpz(1) >>> +_g.mpf(1) mpf('1.e0') >>> +_g.mpq(1) mpq(1) >>> _g.mpz(2)**-2 Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow with negative power >>> _g.mpz(2)**_g.mpz(1000000*1000000L) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow outrageous exponent >>> pow(_g.mpz(2),3,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow divide by zero >>> pow(_g.mpz(2),3,-5) mpz(-2) >>> pow(_g.mpq(2),3,-5) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow no modulo allowed >>> a=1000000L**2 >>> _g.mpq(2)**a Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow outrageous exp num >>> _g.mpq(2)**_g.mpq(1,a) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow outrageous exp den >>> _g.mpq(2)**0 mpq(1) >>> _g.mpq(2)**-1 mpq(1,2) >>> _g.mpq(2)**_g.mpq(1,2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow fractional exponent, inexact-root >>> _g.mpq(-2)**_g.mpq(1,2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow fractional exponent, nonreal-root >>> _g.mpq(0)**_g.mpq(1,2) mpq(0) >>> _g.mpq(0)**-1 Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq.pow 0 base to <0 exponent >>> _g.mpq(-1)**-1 mpq(-1) >>> _g.mpf(9,100)**2 mpf('8.1e1',100) >>> _g.mpf(9,100)**0.5 mpf('3.e0',100) >>> _g.mpf(9,100)**_g.mpf(0.5) mpf('3.e0') >>> pow(_g.mpf(2),3,-5) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpf.pow no modulo allowed >>> _g.mpz(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpz type failed >>> _g.mpz(1)+_g.mpf(1) mpf('2.e0') >>> _g.mpz(1)+_g.mpq(1) mpq(2) >>> _g.mpq(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpq type failed >>> _g.mpf(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpf type failed >>> _g.mpf(1)+_g.mpq(2) mpq(3) >>> divmod(_g.mpz(3),0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpz.divmod by zero >>> divmod(_g.mpz(0),3) (mpz(0), mpz(0)) >>> _g.divm(1,2,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: not invertible >>> abs(_g.mpq(0)) mpq(0) >>> _g.mpz(0)**2 mpz(0) >>> _g.mpq(-2)**0 mpq(1) >>> _g.fac(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: factorial of negative number >>> _g.fib(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Fibonacci of negative number >>> _g.comb(7,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: binomial coefficient with negative k >>> _g.sqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.sqrtrem(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.fsqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (extra cover)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching" \ "(%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with empty callbacks" def _zd(where,*args): if where=='qdiv': raise ZeroDivisionError, "qdiv: zero divisor" elif where=='mpz_divmod': raise ZeroDivisionError, "mpz.divmod by zero" elif where=='mpq_pow': raise ZeroDivisionError, "mpq.pow 0 base to <0 exponent" elif where=='divm': raise ZeroDivisionError, "not invertible" else: raise ZeroDivisionError, "mpq: zero denominator" def _zm(*args): return None def _at(self,name): return name.upper() def _er(where, what, *args): raise ValueError, what _g.set_callback('ZM',_zm) _g.set_callback('ZD',_zd) _g.set_callback('ER',_er) _g.set_callback('AT',_at) class _Fakenum: def __gmpy__(self, where, args, other, extype, exvalue): raise extype, exvalue _fn = _Fakenum() try: x = _g.getbit(_fn,17) except TypeError: pass try: x = _g.divm(23,45,_fn) except TypeError: pass assert(_g.mpz(23).foop=='FOOP') assert(_g.mpq(23).foop=='FOOP') assert(_g.mpf(23).foop=='FOOP') # avoid merge-reports for the second run sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav # just generate a little extra coverage...! _g.set_callback('ZM') _g.set_callback('ZD',None) _g.set_callback('ER') _g.set_callback('AT') try: _g.set_callback('ZD',23,45) except: pass try: _g.set_callback('ZD',23) except: pass try: _g.set_callback('ZZ') except: pass if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_mpf.py --- # partial unit test for gmpy 1.0 mpf functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 1.0 r''' >>> dir(a) ['_copy', 'binary', 'ceil', 'digits', 'f2q', 'floor', 'getprec', 'getrprec', 'qdiv', 'reldiff', 'setprec', 'sign', 'sqrt', 'trunc'] >>> ''' import gmpy as _g, doctest, sys __test__={} a=_g.mpf('123.456') b=_g.mpf('789.123') __test__['elemop']=\ r''' >>> print a+b 912.579 >>> print a-b -665.667 >>> print a*b 97421.969088 >>> print a/b 0.156447093799065544915 >>> print b+a 912.579 >>> print b-a 665.667 >>> print b*a 97421.969088 >>> print b/a 6.39193720839813374806 >>> print -a -123.456 >>> print abs(-a) 123.456 >>> _g.fsign(b-a) 1 >>> _g.fsign(b-b) 0 >>> _g.fsign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> import math >>> math.ceil(a) 124.0 >>> print a.ceil() 124.0 >>> print _g.ceil(a) 124.0 >>> math.floor(a) 123.0 >>> print a.floor() 123.0 >>> print _g.floor(a) 123.0 >>> print a.trunc() 123.0 >>> print _g.trunc(a) 123.0 >>> x=-a >>> math.floor(x) -124.0 >>> print x.floor() -124. >>> print _g.floor(x) -124. >>> print x.ceil() -123. >>> math.ceil(x) -123.0 >>> print _g.ceil(x) -123. >>> print x.trunc() -123. >>> print _g.trunc(x) -123. >>> _g.ceil(12.3)==math.ceil(12.3) 1 >>> _g.floor(12.3)==math.floor(12.3) 1 >>> _g.ceil(-12.3)==math.ceil(-12.3) 1 >>> _g.floor(-12.3)==math.floor(-12.3) 1 >>> (a**2).reldiff(float(a)**2) < (2.0**-(a.getrprec()-1)) 1 >>> (a**2).reldiff(a*a) < (2.0**-(a.getprec()-1)) 1 >>> (b**2).reldiff(float(b)**2) < (2.0**-(b.getrprec()-1)) 1 >>> (b**2).reldiff(b*b) < (2.0**-(b.getprec()-1)) 1 >>> a.sqrt() mpf('1.11110755554986664846e1') >>> _g.fsqrt(a) mpf('1.11110755554986664846e1') >>> _g.fsqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? File "a.py", line 9, in _er raise ValueError, what ValueError: sqrt of negative number >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpf(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpf(0) 1 >>> not a 0 >>> coerce(a,1) (mpf('1.23456e2'), mpf('1.e0')) >>> coerce(1,a) (mpf('1.e0'), mpf('1.23456e2')) >>> coerce(a,1.0) (mpf('1.23456e2'), mpf('1.e0')) >>> a.f2q(0.1) mpz(123) >>> a.f2q(0.01) mpz(123) >>> a.f2q(0.001) mpq(247,2) >>> a.f2q(0.0001) mpq(1358,11) >>> a.f2q(0.00001) mpq(7037,57) >>> a.f2q(0.000001) mpq(15432,125) >>> a.f2q(0.0000001) mpq(15432,125) >>> a.f2q() mpq(15432,125) >>> print _g.mpf(_g.mpz(1234)) 1234.0 >>> x=1000*1000*1000*1000L >>> _g.mpf(x) mpf('1.e12') >>> c=_g.mpf(a) >>> a is c 1 >>> c=_g.mpf(a,99) >>> a is c 0 >>> a==c 1 >>> ''' __test__['format']=\ r''' >>> str(a) '123.456' >>> repr(a) "mpf('1.23456e2')" >>> _g.set_tagoff(0) 1 >>> a gmpy.mpf('1.23456e2') >>> _g.set_tagoff(1) 0 >>> a.digits(10,0) '1.23456e2' >>> a.digits(10,1) '1.e2' >>> a.digits(10,2) '1.2e2' >>> a.digits(10,3) '1.23e2' >>> a.digits(10,4) '1.235e2' >>> a.digits(10,5) '1.2346e2' >>> a.digits(10,6) '1.23456e2' >>> a.digits(10,7) '1.23456e2' >>> a.digits(10,8) '1.23456e2' >>> junk=_g.set_fcoform(14) >>> frmt=_g.set_fcoform(14) >>> frmt '%.14e' >>> ofmt=_g.set_fcoform(frmt) >>> ofmt '%.14e' >>> _g.mpf(3.4) mpf('3.4e0') >>> print _g.mpf(3.4) 3.4 >>> for i in range(11,99): ... assert str(_g.mpf(i/10.0))==str(i/10.0) ... >>> a.digits(1) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: base must be either 0 or in the interval 2 ... 36 >>> a.digits(2,-1) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: digits must be >= 0 >>> a.digits(10,0,0,-1,2) ('123456', 3, 53) >>> saveprec=a.getrprec() >>> a.setprec(33) >>> a mpf('1.23456e2',33) >>> a.setprec(saveprec) >>> a.getrprec()==saveprec 1 >>> _g.fdigits(2.2e5, 0, 6, -10, 10) '220000.0' >>> _g.fdigits(2.2e-5, 0, 6, -10, 10) '0.000022' >>> _g.digits(_g.mpf(23.45)) '23' >>> _g.fbinary('pep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpf >>> ''' __test__['binio']=\ r''' >>> epsilon=_g.mpf(2)**-(a.getrprec()) >>> ba=a.binary() >>> a.reldiff(_g.mpf(ba,0,256)) <= epsilon 1 >>> len(ba) 18 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 8 53 0 0 0 1 0 0 0 123 116 188 106 126 249 219 34 209 >>> na=(-a).binary() >>> (-a).reldiff(_g.mpf(na,0,256)) <= epsilon 1 >>> na[0] == chr(ord(ba[0])|1) 1 >>> for bd,nd in zip(ba[1:],na[1:]): ... assert bd==nd >>> ia=(1/a).binary() >>> (1/a).reldiff(_g.mpf(ia,0,256)) <= epsilon 1 >>> _g.fbinary(0) '\x085\x00\x00\x00\x00\x00\x00\x00' >>> _g.fbinary(0.5) '\x085\x00\x00\x00\x00\x00\x00\x00\x80' >>> _g.fbinary(-0.5) '\t5\x00\x00\x00\x00\x00\x00\x00\x80' >>> _g.fbinary(-2.0) '\t5\x00\x00\x00\x01\x00\x00\x00\x02' >>> _g.fbinary(2.0) '\x085\x00\x00\x00\x01\x00\x00\x00\x02' >>> prec=_g.set_minprec(0) >>> junk=_g.set_minprec(prec) >>> a.getrprec()==prec 1 >>> b.getrprec()==prec 1 >>> _g.mpf(1.0).getrprec()==prec 1 >>> hash(_g.mpf(23.0))==hash(23) 1 >>> print _g.mpf('\004',0,256) 0.0 >>> long(a) 123L >>> long(-a) -123L >>> int(a) 123 >>> int(-a) -123 >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (mpf functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print print "Overall results for mpf:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_mpq.py --- # partial unit test for gmpy 1.0 mpq functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 1.0 r''' >>> dir(a) ['_copy', 'binary', 'denom', 'digits', 'numer', 'qdiv', 'sign'] >>> ''' import gmpy as _g, doctest,sys __test__={} a=_g.mpq('123/456') b=_g.mpq('789/123') __test__['elemop']=\ r''' >>> a+b mpq(41657,6232) >>> a-b mpq(-38295,6232) >>> a*b mpq(263,152) >>> a/b mpq(1681,39976) >>> b+a mpq(41657,6232) >>> b-a mpq(38295,6232) >>> b*a mpq(263,152) >>> b/a mpq(39976,1681) >>> a+1 mpq(193,152) >>> 1+a mpq(193,152) >>> a-1 mpq(-111,152) >>> 1-a mpq(111,152) >>> a*1 mpq(41,152) >>> 1*a mpq(41,152) >>> a/1 mpq(41,152) >>> 1/a mpq(152,41) >>> -a mpq(-41,152) >>> abs(-a) mpq(41,152) >>> _g.qsign(b-a) 1 >>> _g.qsign(b-b) 0 >>> _g.qsign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> an=a.numer(); ad=a.denom(); >>> an==0 or 1==a*_g.mpq(ad,an) 1 >>> bn=b.numer(); bd=b.denom(); >>> bn==0 or 1==b*_g.mpq(bd,bn) 1 >>> zn=z.numer(); zd=z.denom(); >>> zn==0 or 1==z*_g.mpq(zd,zn) 1 >>> (a+b) == _g.mpq(an*bd+ad*bn,ad*bd) 1 >>> (a+z) == _g.mpq(an*zd+ad*zn,ad*zd) 1 >>> (a+a) == _g.mpq(an*ad+ad*an,ad*ad) 1 >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpq(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpq(0) 1 >>> not a 0 >>> coerce(a,1) (mpq(41,152), mpq(1)) >>> coerce(1,a) (mpq(1), mpq(41,152)) >>> coerce(a,1.0) (mpq(41,152), mpq(1)) >>> coerce(a,_g.mpz(1)) (mpq(41,152), mpq(1)) >>> coerce(a,_g.mpf(1)) (mpq(41,152), mpq(1)) >>> a>1 0 >>> a>1.0 0 >>> a<1 1 >>> a<1.0 1 >>> a==1 0 >>> a==1.0 0 >>> cmp(a,1) -1 >>> cmp(1.0,a) 1 >>> long(1/a) 3L >>> long(-1/a) -3L >>> int(1/a) 3 >>> int(-1/a) -3 >>> ''' __test__['format']=\ r''' >>> str(a) '41/152' >>> repr(a) 'mpq(41,152)' >>> a==eval(repr(a),_g.__dict__) 1 >>> str(-a) '-41/152' >>> repr(-a) 'mpq(-41,152)' >>> (-a)==eval(repr(-a),_g.__dict__) 1 >>> _g.set_tagoff(0) 1 >>> a gmpy.mpq(41,152) >>> _g.set_tagoff(1) 0 >>> for i in range(1,7): ... for j in range(3,10): ... if _g.mpq(i,j) != _g.mpq("%d/%d"%(i,j)): ... print 'er1:',i,j; break ... aa=_g.mpq(i,j); ai=aa.numer(); aj=aa.denom() ... if aj!=1 and str(aa) != ("%d/%d"%(ai,aj)): ... print 'er2:',i,j,str(aa),("%d/%d"%(ai,aj)); break ... if aj==1 and str(aa) != ("%d"%ai): ... print 'er3:',i,j,str(aa),"%d"%ai; break ... if aj!=1 and repr(aa) != ("mpq(%d,%d)"%(ai,aj)): ... print 'er4:',i,j,repr(aa),("mpq(%d,%d)"%(ai,aj)); break ... if aj==1 and repr(aa) != ("mpq(%d)"%ai): ... print 'er5:',i,j,repr(aa),"mpq(%d)"%ai; break >>> fmo='_g.mpq('+a.numer().digits(16)+','+a.denom().digits(16)+')' >>> fmo '_g.mpq(0x29,0x98)' >>> eval(fmo)==a 1 >>> fmo='_g.mpq("'+a.numer().digits(30)+'/'+a.denom().digits(30)+'",30)' >>> fmo '_g.mpq("1b/52",30)' >>> eval(fmo)==a 1 >>> _g.qdigits(a,30) '1b/52' >>> a.digits(30) '1b/52' >>> _g.mpq(1000*1000*1000*1000L,23) mpq(1000000000000L,23) >>> _g.mpq(23,1000*1000*1000*1000L) mpq(23,1000000000000L) >>> _g.mpq(23L**10L,1000L**4L) mpq(41426511213649L,1000000000000L) >>> _g.qbinary('pep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpq >>> ''' __test__['binio']=\ r''' >>> ba=a.binary() >>> len(ba) 6 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 1 0 0 0 41 152 >>> _g.mpq(ba,256)==a 1 >>> ba == _g.qbinary(a) 1 >>> ba=(-a).binary() >>> len(ba) 6 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 1 0 0 128 41 152 >>> _g.mpq(ba,256)==-a 1 >>> hash(a)==hash(_g.mpf(a))==hash(float(a)) 1 >>> hash(b)==hash(_g.mpf(b))==hash(float(b)) 1 >>> hash(-a)==hash(-_g.mpf(a))==hash(-float(a)) 1 >>> hash(-b)==hash(-_g.mpf(b))==hash(-float(b)) 1 >>> ''' __test__['power']=\ r''' >>> _g.mpq(2,3)**3 mpq(8,27) >>> _g.mpq(8,27)**_g.mpq('2/3') mpq(4,9) >>> _g.mpq(2,3)**-3 mpq(27,8) >>> _g.mpq(8,27)**_g.mpq('-2/3') mpq(9,4) >>> print float(_g.mpf('0.2')**2) 0.04 >>> print float(_g.mpf('0.2')**-2) 25.0 >>> _g.mpq(3)**3 == _g.mpz(3)**3 1 >>> (a**-7) == 1/(a**7) 1 >>> (b**5) == 1/(b**-5) 1 >>> ''' __test__['qdiv']=\ r''' >>> _g.qdiv(12,2) mpz(6) >>> _g.qdiv(12,5) mpq(12,5) >>> a is a.qdiv() 1 >>> a is a.qdiv(1) 1 >>> a is a.qdiv(2) 0 >>> x=a.numer() >>> x is _g.qdiv(x) 1 >>> x is _g.qdiv(x,1) 1 >>> x is _g.qdiv(x,2) 0 >>> y=_g.mpq(4,1) >>> y is y.qdiv() 0 >>> y == y.qdiv() 1 >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (mpq functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with caching disabled" _g.set_qcache(0) sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_mpz.py --- # partial unit test for gmpy 1.0 mpz functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 1.0 r''' >>> filter(lambda x: not x.startswith('_'), dir(_g)) ['binary', 'bincoef', 'ceil', 'comb', 'denom', 'digits', 'divm', 'f2q', 'fac', 'fbinary', 'fdigits', 'fib', 'floor', 'fsign', 'fsqrt', 'gcd', 'gcdext', 'get_qcache', 'get_zcache', 'get_zconst', 'getbit', 'getprec', 'getrprec', 'gmp_version', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'lcm', 'legendre', 'lowbits', 'mpf', 'mpq', 'mpz', 'next_prime', 'numdigits', 'numer', 'pi', 'popcount', 'qbinary', 'qdigits', 'qdiv', 'qsign', 'rand', 'reldiff', 'remove', 'root', 'scan0', 'scan1', 'set_callback', 'set_debug', 'set_fcoform', 'set_minprec', 'set_qcache', 'set_tagoff', 'set_zcache', 'set_zconst', 'setbit', 'sign', 'sqrt', 'sqrtrem', 'trunc', 'version'] >>> dir(a) ['_copy', 'binary', 'bincoef', 'comb', 'digits', 'getbit', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'legendre', 'lowbits', 'next_prime', 'numdigits', 'popcount', 'qdiv', 'remove', 'root', 'scan0', 'scan1', 'setbit', 'sign', 'sqrt', 'sqrtrem'] >>> ''' import gmpy as _g, doctest,sys __test__={} a=_g.mpz(123) b=_g.mpz(456) def factorize(x): r''' >>> factorize(a) [3, 41] >>> factorize(b) [2, 2, 2, 3, 19] >>> ''' import gmpy as _g savex=x prime=2 x=_g.mpz(x) factors=[] while x>=prime: newx,mult=x.remove(prime) if mult: factors.extend([int(prime)]*mult) x=newx prime=_g.next_prime(prime) for factor in factors: assert _g.is_prime(factor) from operator import mul assert reduce(mul, factors)==savex return factors __test__['elemop']=\ r''' >>> a+b mpz(579) >>> a-b mpz(-333) >>> a*b mpz(56088) >>> a/b mpz(0) >>> a%b mpz(123) >>> b+a mpz(579) >>> b-a mpz(333) >>> b*a mpz(56088) >>> b%a mpz(87) >>> divmod(a,b) (mpz(0), mpz(123)) >>> divmod(b,a) (mpz(3), mpz(87)) >>> -a mpz(-123) >>> abs(-a)==a 1 >>> pow(a,7) mpz(425927596977747L) >>> pow(a,7,b) mpz(99) >>> _g.sign(b-a) 1 >>> _g.sign(b-b) 0 >>> _g.sign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpz(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpz(0) 1 >>> not a 0 >>> coerce(a,1) (mpz(123), mpz(1)) >>> coerce(1,a) (mpz(1), mpz(123)) >>> coerce(a,1.0) (123.0, 1.0) >>> _g.mpz(3.14) mpz(3) >>> _g.mpz(_g.mpq(17,3)) mpz(5) >>> _g.mpz(23L) mpz(23) >>> _g.mpz(-23L) mpz(-23) >>> x=1000*1000*1000*1000L >>> _g.mpz(x) mpz(1000000000000L) >>> ''' __test__['bitops']=\ r''' >>> ~a mpz(-124) >>> a&b mpz(72) >>> a|b mpz(507) >>> a^b mpz(435) >>> a<<1 mpz(246) >>> a>>1 mpz(61) >>> a<<-1 Traceback (innermost last): File "<pyshell#42>", line 1, in ? a<<-1 ValueError: Pympz_lshift negative shift count >>> a>>-2 Traceback (innermost last): File "<pyshell#43>", line 1, in ? a>>-2 ValueError: Pympz_rshift negative shift count >>> a<<0 mpz(123) >>> a>>0 mpz(123) >>> a.popcount() 6 >>> _g.popcount(b) 4 >>> _g.popcount(-7) -1 >>> _g.popcount(0) 0 >>> a.hamdist(b) 6 >>> a.lowbits(5) mpz(27) >>> b.lowbits(5) mpz(8) >>> b.lowbits(5)==(b%32) 1 >>> a.lowbits(5)==(a%32) 1 >>> a.setbit(20) mpz(1048699) >>> a.setbit(0,0) mpz(122) >>> for i in range(8): ... print a.getbit(i), ... if i==7: print ... 1 1 0 1 1 1 1 0 >>> for i in range(10): ... print b.getbit(i), ... if i==9: print ... 0 0 0 1 0 0 1 1 1 0 >>> [a.scan0(j) for j in range(33)] [2, 2, 2, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] >>> [a.scan1(j) for j in range(10)] [0, 1, 3, 3, 4, 5, 6, None, None, None] >>> n=_g.mpz(-(7+6*16+5*256+7*4092)) >>> [n.scan0(j) for j in range(18)] [1, 1, 3, 3, 6, 6, 6, 8, 8, 10, 10, 12, 12, 13, 14, -1, None, None] >>> [n.scan1(j) for j in range(33)] [0, 2, 2, 4, 4, 5, 7, 7, 9, 9, 11, 11, 15, 15, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] >>> ''' __test__['format']=\ r''' >>> str(a) '123' >>> repr(a) 'mpz(123)' >>> hex(a) '0x7b' >>> oct(a) '0173' >>> _g.mpz('123') mpz(123) >>> _g.mpz('1001001011',2) mpz(587) >>> _g.mpz('1001001011',2).digits(2) '1001001011' >>> for i in range(2,37): ... print a.digits(i), ... if i%6==0: print ... 1111011 11120 1323 443 323 234 0173 146 123 102 a3 96 8b 83 0x7b 74 6f 69 63 5i 5d 58 53 4n 4j 4f 4b 47 43 3u 3r 3o 3l 3i 3f >>> print a.digits(37) Traceback (innermost last): File "<stdin>", line 1, in ? print a.digits(37) ValueError: base must be either 0 or in the interval 2 ... 36 >>> _g.set_tagoff(0) 1 >>> a gmpy.mpz(123) >>> _g.set_tagoff(1) 0 >>> _g.mpz('43') mpz(43) >>> _g.mpz('043') mpz(43) >>> _g.mpz('43',0) mpz(43) >>> _g.mpz('043',0) mpz(35) >>> _g.mpz('0x43',0) mpz(67) >>> _g.mpz('0x43') Traceback (innermost last): File "<pyshell#181>", line 1, in ? _g.mpz('0x43') ValueError: invalid digits >>> ''' __test__['binio']=\ r''' >>> ba=a.binary() >>> ba '{' >>> _g.mpz(ba,256) mpz(123) >>> _g.mpz(ba,256)==a 1 >>> _g.binary(123) '{' >>> z=_g.mpz('melancholy',256) >>> z mpz(573406620562849222387053L) >>> divmod(z,a) (mpz(4661842443600400182008L), mpz(69)) >>> for i in range(2,37): ... print i,z.numdigits(i), ... if i%6==0: print ... 2 79 3 50 4 40 5 35 6 31 7 29 8 27 9 25 10 24 11 23 12 23 13 22 14 21 15 21 16 20 17 20 18 19 19 19 20 19 21 18 22 18 23 18 24 18 25 18 26 17 27 17 28 17 29 17 30 17 31 16 32 16 33 16 34 16 35 16 36 16 >>> _g.numdigits(23) 2 >>> _g.numdigits(23,2) 5 >>> _g.numdigits(23,99) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: base must be either 0 or in the interval 2 ... 36 >>> hash(a) 123 >>> hash(b) 456 >>> hash(z) -791330233 >>> _g.mpz(_g.binary(-123),256) mpz(-123) >>> long(_g.mpz(-3)) -3L >>> ''' __test__['number']=\ r''' >>> print a.sqrt(), b.sqrt() 11 21 >>> print a.sqrtrem(), b.sqrtrem() (mpz(11), mpz(2)) (mpz(21), mpz(15)) >>> for i in range(5): ... print a.root(i+1),b.root(i+1) ... (mpz(123), 1) (mpz(456), 1) (mpz(11), 0) (mpz(21), 0) (mpz(4), 0) (mpz(7), 0) (mpz(3), 0) (mpz(4), 0) (mpz(2), 0) (mpz(3), 0) >>> a.is_square() 0 >>> a.is_power() 0 >>> _g.is_square(99*99) 1 >>> _g.is_square(99*99*99) 0 >>> _g.is_square(0) 1 >>> _g.is_square(-1) 0 >>> _g.is_power(99*99*99) 1 >>> _g.gcd(a,b) mpz(3) >>> _g.gcdext(a,b) (mpz(3), mpz(-63), mpz(17)) >>> _g.lcm(a,b) mpz(18696) >>> _g.fac(7) mpz(5040) >>> _g.fib(17) mpz(1597) >>> for i in range(10): ... print _g.bincoef(10,i) ... 1 10 45 120 210 252 210 120 45 10 >>> _g.divm(b,a,20) mpz(12) >>> _g.divm(a,b,100) Traceback (innermost last): File "<pyshell#184>", line 1, in ? _g.divm(a,b,100) ZeroDivisionError: not invertible >>> _g.divm(0,1,2) mpz(0) >>> a.invert(100) mpz(87) >>> b.invert(100) mpz(0) >>> _g.comb(3,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: binomial coefficient with negative k >>> _g.sqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.sqrtrem(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.remove(3,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: factor must be > 0 >>> _g.is_prime(3,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: repetition count for is_prime must be positive >>> _g.jacobi(10,3) 1 >>> _g.jacobi(10,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: jacobi's y must be odd prime > 0 >>> _g.legendre(10,3) 1 >>> _g.legendre(10,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: legendres's y must be odd and > 0 >>> _g.kronecker(10,3) 1 >>> _g.kronecker(10,-3) 1 >>> a=1000000L**2 >>> b=a+1 >>> _g.jacobi(a,b) 1 >>> _g.legendre(a,b) 1 >>> _g.kronecker(a,b) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Either arg in Kronecker must fit in an int >>> f=_g.mpf(3.3) >>> f.setprec(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be >=0 >>> _g.rand('init',-1) >>> _g.rand('init',-7) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: size must be in 1..128 >>> _g.rand('init',200) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: size must be in 1..128 >>> _g.rand('qual') 32 >>> _g.rand('floa',-7) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: 'floa' needs arg>=0 ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (mpz functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with caching disabled" _g.set_zcache(0) _g.set_zconst(0,0) sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_rnd.py --- # partial unit test for gmpy 1.0 rand functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 1.0 r''' >>> r <built-in function rand> >>> ''' import gmpy as _g, doctest,sys __test__={} r = _g.rand __test__['rand']=\ r''' >>> r('error',1,2,3) Traceback (most recent call last): File "<string>", line 1, in ? TypeError: function takes exactly 2 arguments (4 given) >>> r('save') Traceback (most recent call last): File "<string>", line 1, in ? RuntimeError: can't save before init >>> r('init',20) >>> r('unkn',99) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: unknown option 'unkn' >>> r('seed',1234) >>> for i in range(5): ... print r('next',100), ... if i==4: print ... 21 75 63 28 27 >>> alis=list("proktelnu") >>> for i in range(10): ... r('shuf',alis) ... print ''.join(alis) ... rtoulpnke eoturlknp plnuetokr ekoprulnt kpoutnrel rutoneklp ukeptnorl onkrlpteu lknteropu enrkutlpo >>> sav=r('save') >>> print sav 774447212137 >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... elnuortpk enutolpkr eropulntk plroutenk ekonrtplu >>> r('seed',sav) >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... epkruotln ekrtuplno eoulrpktn lpourtekn enukotlpr >>> r('seed',sav) >>> for i in range(3): ... print float(r('floa')) ... 0.44833278656 0.547296524048 0.895370483398 >>> r('seed',sav) >>> for i in range(3): ... print float(r('floa',6)) ... 0.484375 0.90625 0.75 >>> r('seed',sav) >>> for i in range(3): ... print _g.f2q(r('floa',6),-6) ... 15/31 9/10 3/4 >>> r('seed',sav) >>> for i in range(3): ... print _g.f2q(r('floa',6)) ... 31/64 29/32 3/4 >>> r('seed',sav) >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... elnorutpk enotrlpku eurpolntk plurotenk ekrnutplo >>> r('shuf','astring') Traceback (most recent call last): File "<string>", line 1, in ? TypeError: object doesn't support item assignment >>> r('shuf',23) Traceback (most recent call last): File "<string>", line 1, in ? TypeError: 'shuf' needs mutable sequence >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (rand functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache() ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print print "Overall results for rnd:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) Index: timing1.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/test/timing1.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** timing1.py 24 Jan 2002 14:20:17 -0000 1.1.1.1 --- timing1.py 8 Aug 2003 08:57:05 -0000 1.2 *************** *** 9,12 **** --- 9,18 ---- return type(zero), stend-start, tot + def timedsum1(n, zero): + start=time.clock() + tot=sum(range(n), zero) + stend=time.clock() + return type(zero), stend-start, tot + def timedmul(n, one): start=time.clock() *************** *** 17,28 **** return type(one), stend-start, tot ! def test(n=10*1000): print "Sum of %d items of various types:" % n for z in 0L, 0.0, gmpy.mpz(0), gmpy.mpf(0): tip, tim, tot = timedsum(n, z) print " %5.3f %.0f %s" % (tim, float(tot), tip) ! print "Mul of %d items of various types:" % n for z in 1L, 1.0, gmpy.mpz(1), gmpy.mpf(1): ! tip, tim, tot = timedmul(n, z) print " %5.3f %s" % (tim, tip) --- 23,38 ---- return type(one), stend-start, tot ! def test(n=100*1000): print "Sum of %d items of various types:" % n for z in 0L, 0.0, gmpy.mpz(0), gmpy.mpf(0): tip, tim, tot = timedsum(n, z) print " %5.3f %.0f %s" % (tim, float(tot), tip) ! print "Sum of %d items of various types w/2.3 sum builtin:" % n ! for z in 0L, 0.0, gmpy.mpz(0), gmpy.mpf(0): ! tip, tim, tot = timedsum1(n, z) ! print " %5.3f %.0f %s" % (tim, float(tot), tip) ! print "Mul of %d items of various types:" % (n//5) for z in 1L, 1.0, gmpy.mpz(1), gmpy.mpf(1): ! tip, tim, tot = timedmul(n//5, z) print " %5.3f %s" % (tim, tip) Index: timing2.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/test/timing2.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** timing2.py 24 Jan 2002 14:20:17 -0000 1.1.1.1 --- timing2.py 8 Aug 2003 08:57:05 -0000 1.2 *************** *** 15,19 **** return type(one), stend-start, result ! def test(n=10*1000): print "%dth Fibonacci number of various types:" % n for z in 0L, gmpy.mpz(0), gmpy.mpf(0): --- 15,19 ---- return type(one), stend-start, result ! def test(n=100*1000): print "%dth Fibonacci number of various types:" % n for z in 0L, gmpy.mpz(0), gmpy.mpf(0): Index: timing3.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/test/timing3.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** timing3.py 24 Jan 2002 14:20:17 -0000 1.1.1.1 --- timing3.py 8 Aug 2003 08:57:05 -0000 1.2 *************** *** 2,13 **** import time ! print "Typical expected results",""" D:\PySym>python timing.py - Factorial of 10 took 9.97333181359e-005 (7 digits) - Fibonacci of 10 took 9.88952230255e-005 (2 digits) - Factorial of 100 took 0.000121523791006 (159 digits) - Fibonacci of 100 took 9.05142719216e-005 (21 digits) - Factorial of 1000 took 0.00173569497361 (2568 digits) - Fibonacci of 1000 took 0.000138285693214 (209 digits) Factorial of 10000 took 0.0619989238859 (35660 digits) Fibonacci of 10000 took 0.000744228458022 (2090 digits) --- 2,7 ---- import time ! print "Typical expected results would be:",""" D:\PySym>python timing.py Factorial of 10000 took 0.0619989238859 (35660 digits) Fibonacci of 10000 took 0.000744228458022 (2090 digits) *************** *** 18,22 **** """ ! for i in (10,100,1000,10000,100000,1000000): start=time.clock() x=_g.fac(i) --- 12,17 ---- """ ! print "Actual timings and results...:" ! for i in (10000,100000,1000000): start=time.clock() x=_g.fac(i) --- doctest.py DELETED --- --- gmpy_test_08.py DELETED --- --- gmpy_test_08_cvr.py DELETED --- --- gmpy_test_08_mpf.py DELETED --- --- gmpy_test_08_mpq.py DELETED --- --- gmpy_test_08_mpz.py DELETED --- --- gmpy_test_08_rnd.py DELETED --- --- gmpy_test_09.py DELETED --- --- gmpy_test_09_cvr.py DELETED --- --- gmpy_test_09_mpf.py DELETED --- --- gmpy_test_09_mpq.py DELETED --- --- gmpy_test_09_mpz.py DELETED --- --- gmpy_test_09_rnd.py DELETED --- |
From: Alex M. <al...@us...> - 2003-08-08 08:57:08
|
Update of /cvsroot/gmpy/gmpy/src In directory sc8-pr-cvs1:/tmp/cvs-serv15488/src Modified Files: gmpy.c gmpy.h pysymbolicext.c Added Files: pymemcompat.h Log Message: Minor updates for 1.0 alpha (supporting Python 2.3) --- NEW FILE: pymemcompat.h --- /* The idea of this file is that you bundle it with your extension, #include it, program to Python 2.3's memory API and have your extension build with any version of Python from 1.5.2 through to 2.3 (and hopefully beyond). */ #ifndef Py_PYMEMCOMPAT_H #define Py_PYMEMCOMPAT_H #include "Python.h" /* There are three "families" of memory API: the "raw memory", "object memory" and "object" families. (This is ignoring the matter of the cycle collector, about which more is said below). Raw Memory: PyMem_Malloc, PyMem_Realloc, PyMem_Free Object Memory: PyObject_Malloc, PyObject_Realloc, PyObject_Free Object: PyObject_New, PyObject_NewVar, PyObject_Del The raw memory and object memory allocators both mimic the malloc/realloc/free interface from ANSI C, but the object memory allocator can (and, since 2.3, does by default) use a different allocation strategy biased towards lots of "small" allocations. The object family is used for allocating Python objects, and the initializers take care of some basic initialization (setting the refcount to 1 and filling out the ob_type field) as well as having a somewhat different interface. Do not mix the families! E.g. do not allocate memory with PyMem_Malloc and free it with PyObject_Free. You may get away with it quite a lot of the time, but there *are* scenarios where this will break. You Have Been Warned. Also, in many versions of Python there are an insane amount of memory interfaces to choose from. Use the ones described above. */ #if PY_VERSION_HEX < 0x01060000 /* raw memory interface already present */ /* there is no object memory interface in 1.5.2 */ #define PyObject_Malloc PyMem_Malloc #define PyObject_Realloc PyMem_Realloc #define PyObject_Free PyMem_Free /* the object interface is there, but the names have changed */ #define PyObject_New PyObject_NEW #define PyObject_NewVar PyObject_NEW_VAR #define PyObject_Del PyMem_Free #endif /* If your object is a container you probably want to support the cycle collector, which was new in Python 2.0. Unfortunately, the interface to the collector that was present in Python 2.0 and 2.1 proved to be tricky to use, and so changed in 2.2 -- in a way that can't easily be papered over with macros. This file contains macros that let you program to the 2.2 GC API. Your module will compile against any Python since version 1.5.2, but the type will only participate in the GC in versions 2.2 and up. Some work is still necessary on your part to only fill out the tp_traverse and tp_clear fields when they exist and set tp_flags appropriately. It is possible to support both the 2.0 and 2.2 GC APIs, but it's not pretty and this comment block is too narrow to contain a desciption of what's required... */ #if PY_VERSION_HEX < 0x020200B1 #define PyObject_GC_New PyObject_New #define PyObject_GC_NewVar PyObject_NewVar #define PyObject_GC_Del PyObject_Del #define PyObject_GC_Track(op) #define PyObject_GC_UnTrack(op) #endif #endif /* !Py_PYMEMCOMPAT_H */ Index: gmpy.c =================================================================== RCS file: /cvsroot/gmpy/gmpy/src/gmpy.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** gmpy.c 5 Mar 2002 22:29:04 -0000 1.5 --- gmpy.c 8 Aug 2003 08:57:05 -0000 1.6 *************** *** 7,10 **** --- 7,11 ---- * Version for GMP-4, Python-2, with support for MSVC++6. * addition of mpf's, &c: Alex Martelli (al...@ya..., Nov 2000). + * cleanups & reorgs leading to 1.0: Alex Martelli (until Aug 2003) * * Some hacks by Gustavo Niemeyer <nie...@co...>. *************** *** 101,105 **** --- 102,111 ---- * updated tests to 0.9, better coverage * + * 1.0: + * minor cleanups, ensure support for Python 2.3 + * */ + #include "pymemcompat.h" + #include <assert.h> #include <math.h> *************** *** 107,111 **** #include <stdio.h> - #include "Python.h" #define GMPY_MODULE #include "gmpy.h" --- 113,116 ---- *************** *** 121,125 **** #endif ! char gmpy_version[] = "0.9.0c"; /* --- 126,130 ---- #endif ! char gmpy_version[] = "1.0"; /* *************** *** 404,408 **** PympzObject * self; ! if(!(self = PyObject_NEW(PympzObject, &Pympz_Type))) return NULL; /* MPOBCAL(self)=0; MPOBFLA(self)=0; */ --- 409,413 ---- PympzObject * self; ! if(!(self = PyObject_New(PympzObject, &Pympz_Type))) return NULL; /* MPOBCAL(self)=0; MPOBFLA(self)=0; */ *************** *** 415,419 **** PympqObject * self; ! if(!(self = PyObject_NEW(PympqObject, &Pympq_Type))) return NULL; /* MPOBCAL(self)=0; MPOBFLA(self)=0; */ --- 420,424 ---- PympqObject * self; ! if(!(self = PyObject_New(PympqObject, &Pympq_Type))) return NULL; /* MPOBCAL(self)=0; MPOBFLA(self)=0; */ *************** *** 426,430 **** PympfObject * self; ! if(!(self = PyObject_NEW(PympfObject, &Pympf_Type))) return NULL; /* MPOBCAL(self)=0; MPOBFLA(self)=0; */ --- 431,435 ---- PympfObject * self; ! if(!(self = PyObject_New(PympfObject, &Pympf_Type))) return NULL; /* MPOBCAL(self)=0; MPOBFLA(self)=0; */ *************** *** 443,447 **** mpz_cloc_m(self->z); /* Py_XDECREF(MPOBCAL(self)); */ ! PyMem_DEL(self); } /* Pympz_dealloc */ static void --- 448,452 ---- mpz_cloc_m(self->z); /* Py_XDECREF(MPOBCAL(self)); */ ! PyObject_Del(self); } /* Pympz_dealloc */ static void *************** *** 452,456 **** mpq_cloc_m(self->q); /* Py_XDECREF(MPOBCAL(self)); */ ! PyMem_DEL(self); } /* Pympq_dealloc */ static void --- 457,461 ---- mpq_cloc_m(self->q); /* Py_XDECREF(MPOBCAL(self)); */ ! PyObject_Del(self); } /* Pympq_dealloc */ static void *************** *** 461,465 **** mpf_clear(self->f); /* Py_XDECREF(MPOBCAL(self)); */ ! PyMem_DEL(self); } /* Pympz_dealloc */ --- 466,470 ---- mpf_clear(self->f); /* Py_XDECREF(MPOBCAL(self)); */ ! PyObject_Del(self); } /* Pympz_dealloc */ Index: gmpy.h =================================================================== RCS file: /cvsroot/gmpy/gmpy/src/gmpy.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** gmpy.h 24 Jan 2002 14:19:25 -0000 1.1.1.1 --- gmpy.h 8 Aug 2003 08:57:05 -0000 1.2 *************** *** 5,9 **** Created by Pearu Peterson <pe...@ce...>, November 2000. Edited by A. Martelli <al...@ya...>, December 2000. ! Version 0.8. */ --- 5,9 ---- Created by Pearu Peterson <pe...@ce...>, November 2000. Edited by A. Martelli <al...@ya...>, December 2000. ! Version 1.0, August 2003. */ Index: pysymbolicext.c =================================================================== RCS file: /cvsroot/gmpy/gmpy/src/pysymbolicext.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** pysymbolicext.c 24 Jan 2002 14:19:31 -0000 1.1.1.1 --- pysymbolicext.c 8 Aug 2003 08:57:05 -0000 1.2 *************** *** 16,19 **** --- 16,20 ---- */ + #include "Python.h" #include <assert.h> *************** *** 22,26 **** #include <string.h> - #include "Python.h" #include "gmpy.h" --- 23,26 ---- *************** *** 344,352 **** factor_using_division (t, division_limit, res); ! if (mpz_cmp_ui (t, 1) != 0) if (mpz_probab_prime_p (t, 3)) res_append_mpz(res,t,1); else factor_using_pollard_rho (t, 1, p, res); } --- 344,353 ---- factor_using_division (t, division_limit, res); ! if (mpz_cmp_ui (t, 1) != 0) { if (mpz_probab_prime_p (t, 3)) res_append_mpz(res,t,1); else factor_using_pollard_rho (t, 1, p, res); + } } |
From: Alex M. <al...@us...> - 2003-08-08 08:57:08
|
Update of /cvsroot/gmpy/gmpy In directory sc8-pr-cvs1:/tmp/cvs-serv15488 Modified Files: setes.py setup.py Log Message: Minor updates for 1.0 alpha (supporting Python 2.3) Index: setes.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/setes.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** setes.py 24 Jan 2002 14:17:06 -0000 1.1.1.1 --- setes.py 8 Aug 2003 08:57:05 -0000 1.2 *************** *** 3,15 **** if sys.version.find('MSC')==-1: ! gmpy_ext = Extension('pysymbolicext', sources=['pysymbolicext.c'], libraries=['gmp']) else: ! gmpy_ext = Extension('pysymbolicext', sources=['pysymbolicext.c'], ! libraries=['gmp'],include_dirs=['.']) setup (name = "pysymbolicext", version = "0.2", ! description = "GMP-3 to Python-2 interface", maintainer = "Alex Martelli", maintainer_email = "al...@ya...", --- 3,16 ---- if sys.version.find('MSC')==-1: ! gmpy_ext = Extension('pysymbolicext', sources=['src/pysymbolicext.c'], libraries=['gmp']) else: ! gmpy_ext = Extension('pysymbolicext', sources=['src/pysymbolicext.c'], ! libraries=['gmp'],include_dirs=['./src']) setup (name = "pysymbolicext", version = "0.2", ! description = "PySymbolic Python/GMP extensions (Pollard's rho)", ! author = "Pearu Peterson", maintainer = "Alex Martelli", maintainer_email = "al...@ya...", Index: setup.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/setup.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** setup.py 5 Mar 2002 11:05:10 -0000 1.3 --- setup.py 8 Aug 2003 08:57:05 -0000 1.4 *************** *** 11,15 **** setup (name = "gmpy", ! version = "0.9.0c", description = "GMP-3 to Python-2 interface", maintainer = "Alex Martelli", --- 11,15 ---- setup (name = "gmpy", ! version = "1.0", description = "GMP-3 to Python-2 interface", maintainer = "Alex Martelli", |
From: Alex M. <al...@us...> - 2002-03-05 22:29:08
|
Update of /cvsroot/gmpy/gmpy/test In directory usw-pr-cvs1:/tmp/cvs-serv22810/test Modified Files: gmpy_test_09_mpz.py Log Message: Fixed minor glitches. Index: gmpy_test_09_mpz.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/test/gmpy_test_09_mpz.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** gmpy_test_09_mpz.py 5 Mar 2002 11:06:48 -0000 1.1 --- gmpy_test_09_mpz.py 5 Mar 2002 22:29:04 -0000 1.2 *************** *** 4,8 **** r''' >>> filter(lambda x: not x.startswith('_'), dir(_g)) ! ['binary', 'bincoef', 'ceil', 'comb', 'denom', 'digits', 'divm', 'f2q', 'fac', 'fbinary', 'fdigits', 'fib', 'floor', 'fsign', 'fsqrt', 'gcd', 'gcdext', 'get_qcache', 'get_zcache', 'get_zconst', 'getbit', 'getprec', 'getrprec', 'gmp_version', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'lcm', 'legendre', 'lowbits', 'mpf', 'mpq', 'mpz', 'next_prime', 'numdigits', 'numer', 'popcount', 'qbinary', 'qdigits', 'qdiv', 'qsign', 'rand', 'reldiff', 'remove', 'root', 'scan0', 'scan1', 'set_callback', 'set_debug', 'set_fcoform', 'set_minprec', 'set_qcache', 'set_tagoff', 'set_zcache', 'set_zconst', 'setbit', 'sign', 'sqrt', 'sqrtrem', 'trunc', 'version'] >>> dir(a) ['_copy', 'binary', 'bincoef', 'comb', 'digits', 'getbit', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'legendre', 'lowbits', 'next_prime', 'numdigits', 'popcount', 'qdiv', 'remove', 'root', 'scan0', 'scan1', 'setbit', 'sign', 'sqrt', 'sqrtrem'] --- 4,8 ---- r''' >>> filter(lambda x: not x.startswith('_'), dir(_g)) ! ['binary', 'bincoef', 'ceil', 'comb', 'denom', 'digits', 'divm', 'f2q', 'fac', 'fbinary', 'fdigits', 'fib', 'floor', 'fsign', 'fsqrt', 'gcd', 'gcdext', 'get_qcache', 'get_zcache', 'get_zconst', 'getbit', 'getprec', 'getrprec', 'gmp_version', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'lcm', 'legendre', 'lowbits', 'mpf', 'mpq', 'mpz', 'next_prime', 'numdigits', 'numer', 'pi', 'popcount', 'qbinary', 'qdigits', 'qdiv', 'qsign', 'rand', 'reldiff', 'remove', 'root', 'scan0', 'scan1', 'set_callback', 'set_debug', 'set_fcoform', 'set_minprec', 'set_qcache', 'set_tagoff', 'set_zcache', 'set_zconst', 'setbit', 'sign', 'sqrt', 'sqrtrem', 'trunc', 'version'] >>> dir(a) ['_copy', 'binary', 'bincoef', 'comb', 'digits', 'getbit', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'legendre', 'lowbits', 'next_prime', 'numdigits', 'popcount', 'qdiv', 'remove', 'root', 'scan0', 'scan1', 'setbit', 'sign', 'sqrt', 'sqrtrem'] |
From: Alex M. <al...@us...> - 2002-03-05 22:29:08
|
Update of /cvsroot/gmpy/gmpy/src In directory usw-pr-cvs1:/tmp/cvs-serv22810/src Modified Files: gmpy.c Log Message: Fixed minor glitches. Index: gmpy.c =================================================================== RCS file: /cvsroot/gmpy/gmpy/src/gmpy.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** gmpy.c 5 Mar 2002 21:04:08 -0000 1.4 --- gmpy.c 5 Mar 2002 22:29:04 -0000 1.5 *************** *** 121,125 **** #endif ! char gmpy_version[] = "0.9.0b"; /* --- 121,125 ---- #endif ! char gmpy_version[] = "0.9.0c"; /* *************** *** 5135,5139 **** PympzObject *resob = Pympz_new(); if(resob) { ! #if __GNU_MP_ >= 4 mpz_set(resob->z, randstate->_mp_seed); #else --- 5135,5139 ---- PympzObject *resob = Pympz_new(); if(resob) { ! #if __GNU_MP__ >= 4 mpz_set(resob->z, randstate->_mp_seed); #else |
From: Gustavo N. <nie...@us...> - 2002-03-05 21:04:13
|
Update of /cvsroot/gmpy/gmpy/src In directory usw-pr-cvs1:/tmp/cvs-serv25379/src Modified Files: gmpy.c Log Message: Fixed a little compatibility bug, so gmpy work with old gmp libraries (old gmp uses seed, not _mp_seed). Index: gmpy.c =================================================================== RCS file: /cvsroot/gmpy/gmpy/src/gmpy.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** gmpy.c 5 Mar 2002 11:05:11 -0000 1.3 --- gmpy.c 5 Mar 2002 21:04:08 -0000 1.4 *************** *** 5135,5139 **** --- 5135,5143 ---- PympzObject *resob = Pympz_new(); if(resob) { + #if __GNU_MP_ >= 4 mpz_set(resob->z, randstate->_mp_seed); + #else + mpz_set(resob->z, randstate->seed); + #endif result = (PyObject*)resob; } |
From: Alex M. <al...@us...> - 2002-03-05 11:06:51
|
Update of /cvsroot/gmpy/gmpy/test In directory usw-pr-cvs1:/tmp/cvs-serv7608/test Added Files: gmpy_test_09.py gmpy_test_09_cvr.py gmpy_test_09_mpf.py gmpy_test_09_mpq.py gmpy_test_09_mpz.py gmpy_test_09_rnd.py Log Message: Tests updated for release 0.9.0c of gmpy and 4.0.1 of GMP. --- NEW FILE: gmpy_test_09.py --- r''' >>> gmpy.version() '0.9.0c' >>> ''' import sys import doctest import gmpy if sys.argv[-1] == 'debug': gmpy.set_debug(1) import gmpy_test_09_cvr import gmpy_test_09_rnd import gmpy_test_09_mpf import gmpy_test_09_mpq import gmpy_test_09_mpz test_modules = (gmpy_test_09_cvr, gmpy_test_09_rnd, gmpy_test_09_mpf, gmpy_test_09_mpq, gmpy_test_09_mpz ) _g = gmpy print "Unit tests for gmpy 0.9 pre-alpha" print " on Python",sys.version print "Testing gmpy %s (GMP %s), default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) pf, pt = 0, 0 for x in test_modules: print x.__name__, failures, tests = x._test() print "%3d tests, %d failures" % (tests-pt, failures-pf) pf, pt = failures, tests doctest.master.summarize(1) --- NEW FILE: gmpy_test_09_cvr.py --- # partial unit test for gmpy 0.9 extra cover # relies on Tim Peters' "doctest.py" test-driver # test-version 0.9.0c r''' >>> _g.gmp_version() '4.0.1' >>> _g.version() '0.9.0c' ''' import gmpy as _g, doctest, sys __test__={} r = _g.rand __test__['misc_stuff']=\ r''' >>> junk=_g.set_debug(0) >>> knuj=_g.set_debug(junk) >>> junk==_g.set_debug(junk) 1 >>> _g.set_fcoform(None) >>> _g.set_fcoform() >>> print _g.mpf(3.0) 3.0 >>> ''' __test__['user_errors']=\ r''' >>> _g.version(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.gmp_version(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.get_zcache(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_zcache(2000) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_zcache(-23) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.get_qcache(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_qcache(2000) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_qcache(-42) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.get_zconst(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_zconst() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (0 given) >>> _g.set_zconst(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (1 given) >>> _g.set_zconst(23,45,67) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (3 given) >>> _g.set_zconst(23,'blub') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.set_zconst(-1000,1000) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_zconst(100,-100) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_debug() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 1 argument (0 given) >>> _g.set_debug(2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 1 argument (2 given) >>> _g.set_debug('boh') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.set_minprec(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: minimum precision must be >= 0 >>> _g.set_fcoform(33) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: number of digits n must be 0<n<=30 >>> _g.set_fcoform([]) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: set_fcoform argument must be int, string, or None >>> _g.mpz('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpf('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpq('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpq('bo',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (too short) >>> _g.mpq('bologna',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (num len) >>> _g.mpq('\001\000\000\000\003\002',256) mpq(3,2) >>> _g.mpq('\002\000\000\000\003\377\002',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (num sgn) >>> _g.mpq('\001\000\000\000\003\002\377',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (den sgn) >>> _g.mpq('ba/bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> print 'ba/bo' ba/bo >>> _g.mpq('1/bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> print '1/bo' 1/bo >>> _g.mpq('1/0') Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq: zero denominator >>> _g.mpf([]) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() expects numeric or string argument >>> _g.mpf('bo',0,256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string too short to be a gmpy.mpf binary encoding >>> _g.mpf('bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> int(_g.mpz(1000*1000*1000*1000L)) Traceback (most recent call last): File "<stdin>", line 1, in ? OverflowError: mpz too large for int >>> _g.scan0(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: starting bit must be >= 0 >>> _g.scan1(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: starting bit must be >= 0 >>> _g.lowbits(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: nbits must be > 0 >>> _g.getbit(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bit_index must be >= 0 >>> _g.setbit(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bit_index must be >= 0 >>> _g.mpz(23).setbit(12,1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 2 arguments (4 given) >>> _g.setbit(12,1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 3 arguments (4 given) >>> _g.root(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be > 0 >>> _g.root(12,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be > 0 >>> _g.root(-12,2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: root of negative number >>> _g.digits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.fdigits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.qdigits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.mpz(3).digits('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.mpf(3).digits('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.qdiv(3,_g.mpq(1)) mpz(3) >>> _g.qdiv(3,_g.mpz(1)) mpz(3) >>> _g.qdiv(3,_g.mpf(1)) mpz(3) >>> _g.qdiv(3,1.0) mpz(3) >>> _g.qdiv(3,1L) mpz(3) >>> _g.qdiv(3) mpz(3) >>> _g.qdiv(3,'bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: second argument to qdiv not a number >>> _g.mpq(2).qdiv(3,4) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 1 argument (2 given) >>> _g.qdiv(3,4,5) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 2 arguments (3 given) >>> _g.qdiv('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: first argument to qdiv not a number >>> _g.qdiv(1.0,1) mpz(1) >>> _g.qdiv(1.0,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: qdiv: zero divisor >>> _g.f2q(-1.0) mpz(-1) >>> _g.mpz(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() requires 1 or 2 arguments >>> _g.mpz('bi','bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz(): base must be an integer >>> _g.mpz('bi',99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpz must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpz(1,2) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() with numeric argument needs exactly 1 argument >>> _g.mpz(None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() expects numeric or string argument >>> _g.mpq(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq() requires 1 or 2 arguments >>> _g.mpq('bi','bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq(): base must be an integer >>> _g.mpq('bi',99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpq() must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpq(None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq() expects numeric or string argument >>> _g.mpq(1,None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpq >>> _g.mpq(1,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq: zero denominator >>> _g.mpf() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() requires 1 to 3 arguments >>> _g.mpf(1,'bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf(): bits must be an integer >>> _g.mpf(1,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bits for gmpy.mpf must be >= 0 >>> _g.mpf('ba',0,'bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf(): base must be an integer >>> _g.mpf('ba',0,99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpf must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpf(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() with numeric 1st argument needs 1 or 2 arguments >>> +_g.mpz(1) mpz(1) >>> +_g.mpf(1) mpf('1.e0') >>> +_g.mpq(1) mpq(1) >>> _g.mpz(2)**-2 Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow with negative power >>> _g.mpz(2)**_g.mpz(1000000*1000000L) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow outrageous exponent >>> pow(_g.mpz(2),3,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow divide by zero >>> pow(_g.mpz(2),3,-5) mpz(-2) >>> pow(_g.mpq(2),3,-5) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow no modulo allowed >>> a=1000000L**2 >>> _g.mpq(2)**a Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow outrageous exp num >>> _g.mpq(2)**_g.mpq(1,a) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow outrageous exp den >>> _g.mpq(2)**0 mpq(1) >>> _g.mpq(2)**-1 mpq(1,2) >>> _g.mpq(2)**_g.mpq(1,2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow fractional exponent, inexact-root >>> _g.mpq(-2)**_g.mpq(1,2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow fractional exponent, nonreal-root >>> _g.mpq(0)**_g.mpq(1,2) mpq(0) >>> _g.mpq(0)**-1 Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq.pow 0 base to <0 exponent >>> _g.mpq(-1)**-1 mpq(-1) >>> _g.mpf(9,100)**2 mpf('8.1e1',100) >>> _g.mpf(9,100)**0.5 mpf('3.e0',100) >>> _g.mpf(9,100)**_g.mpf(0.5) mpf('3.e0') >>> pow(_g.mpf(2),3,-5) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpf.pow no modulo allowed >>> _g.mpz(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpz type failed >>> _g.mpz(1)+_g.mpf(1) mpf('2.e0') >>> _g.mpz(1)+_g.mpq(1) mpq(2) >>> _g.mpq(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpq type failed >>> _g.mpf(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpf type failed >>> _g.mpf(1)+_g.mpq(2) mpq(3) >>> divmod(_g.mpz(3),0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpz.divmod by zero >>> divmod(_g.mpz(0),3) (mpz(0), mpz(0)) >>> _g.divm(1,2,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: not invertible >>> abs(_g.mpq(0)) mpq(0) >>> _g.mpz(0)**2 mpz(0) >>> _g.mpq(-2)**0 mpq(1) >>> _g.fac(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: factorial of negative number >>> _g.fib(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Fibonacci of negative number >>> _g.comb(7,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: binomial coefficient with negative k >>> _g.sqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.sqrtrem(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.fsqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (extra cover)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching" \ "(%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with empty callbacks" def _zd(where,*args): if where=='qdiv': raise ZeroDivisionError, "qdiv: zero divisor" elif where=='mpz_divmod': raise ZeroDivisionError, "mpz.divmod by zero" elif where=='mpq_pow': raise ZeroDivisionError, "mpq.pow 0 base to <0 exponent" elif where=='divm': raise ZeroDivisionError, "not invertible" else: raise ZeroDivisionError, "mpq: zero denominator" def _zm(*args): return None def _at(self,name): return name.upper() def _er(where, what, *args): raise ValueError, what _g.set_callback('ZM',_zm) _g.set_callback('ZD',_zd) _g.set_callback('ER',_er) _g.set_callback('AT',_at) class _Fakenum: def __gmpy__(self, where, args, other, extype, exvalue): raise extype, exvalue _fn = _Fakenum() try: x = _g.getbit(_fn,17) except TypeError: pass try: x = _g.divm(23,45,_fn) except TypeError: pass assert(_g.mpz(23).foop=='FOOP') assert(_g.mpq(23).foop=='FOOP') assert(_g.mpf(23).foop=='FOOP') # avoid merge-reports for the second run sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav # just generate a little extra coverage...! _g.set_callback('ZM') _g.set_callback('ZD',None) _g.set_callback('ER') _g.set_callback('AT') try: _g.set_callback('ZD',23,45) except: pass try: _g.set_callback('ZD',23) except: pass try: _g.set_callback('ZZ') except: pass if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_09_mpf.py --- # partial unit test for gmpy 0.9 mpf functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 0.9 r''' >>> dir(a) ['_copy', 'binary', 'ceil', 'digits', 'f2q', 'floor', 'getprec', 'getrprec', 'qdiv', 'reldiff', 'setprec', 'sign', 'sqrt', 'trunc'] >>> ''' import gmpy as _g, doctest, sys __test__={} a=_g.mpf('123.456') b=_g.mpf('789.123') __test__['elemop']=\ r''' >>> print a+b 912.579 >>> print a-b -665.667 >>> print a*b 97421.969088 >>> print a/b 0.156447093799065544915 >>> print b+a 912.579 >>> print b-a 665.667 >>> print b*a 97421.969088 >>> print b/a 6.39193720839813374806 >>> print -a -123.456 >>> print abs(-a) 123.456 >>> _g.fsign(b-a) 1 >>> _g.fsign(b-b) 0 >>> _g.fsign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> import math >>> math.ceil(a) 124.0 >>> print a.ceil() 124.0 >>> print _g.ceil(a) 124.0 >>> math.floor(a) 123.0 >>> print a.floor() 123.0 >>> print _g.floor(a) 123.0 >>> print a.trunc() 123.0 >>> print _g.trunc(a) 123.0 >>> x=-a >>> math.floor(x) -124.0 >>> print x.floor() -124. >>> print _g.floor(x) -124. >>> print x.ceil() -123. >>> math.ceil(x) -123.0 >>> print _g.ceil(x) -123. >>> print x.trunc() -123. >>> print _g.trunc(x) -123. >>> _g.ceil(12.3)==math.ceil(12.3) 1 >>> _g.floor(12.3)==math.floor(12.3) 1 >>> _g.ceil(-12.3)==math.ceil(-12.3) 1 >>> _g.floor(-12.3)==math.floor(-12.3) 1 >>> (a**2).reldiff(float(a)**2) < (2.0**-(a.getrprec()-1)) 1 >>> (a**2).reldiff(a*a) < (2.0**-(a.getprec()-1)) 1 >>> (b**2).reldiff(float(b)**2) < (2.0**-(b.getrprec()-1)) 1 >>> (b**2).reldiff(b*b) < (2.0**-(b.getprec()-1)) 1 >>> a.sqrt() mpf('1.11110755554986664846e1') >>> _g.fsqrt(a) mpf('1.11110755554986664846e1') >>> _g.fsqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? File "a.py", line 9, in _er raise ValueError, what ValueError: sqrt of negative number >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpf(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpf(0) 1 >>> not a 0 >>> coerce(a,1) (mpf('1.23456e2'), mpf('1.e0')) >>> coerce(1,a) (mpf('1.e0'), mpf('1.23456e2')) >>> coerce(a,1.0) (mpf('1.23456e2'), mpf('1.e0')) >>> a.f2q(0.1) mpz(123) >>> a.f2q(0.01) mpz(123) >>> a.f2q(0.001) mpq(247,2) >>> a.f2q(0.0001) mpq(1358,11) >>> a.f2q(0.00001) mpq(7037,57) >>> a.f2q(0.000001) mpq(15432,125) >>> a.f2q(0.0000001) mpq(15432,125) >>> a.f2q() mpq(15432,125) >>> print _g.mpf(_g.mpz(1234)) 1234.0 >>> x=1000*1000*1000*1000L >>> _g.mpf(x) mpf('1.e12') >>> c=_g.mpf(a) >>> a is c 1 >>> c=_g.mpf(a,99) >>> a is c 0 >>> a==c 1 >>> ''' __test__['format']=\ r''' >>> str(a) '123.456' >>> repr(a) "mpf('1.23456e2')" >>> _g.set_tagoff(0) 1 >>> a gmpy.mpf('1.23456e2') >>> _g.set_tagoff(1) 0 >>> a.digits(10,0) '1.23456e2' >>> a.digits(10,1) '1.e2' >>> a.digits(10,2) '1.2e2' >>> a.digits(10,3) '1.23e2' >>> a.digits(10,4) '1.235e2' >>> a.digits(10,5) '1.2346e2' >>> a.digits(10,6) '1.23456e2' >>> a.digits(10,7) '1.23456e2' >>> a.digits(10,8) '1.23456e2' >>> junk=_g.set_fcoform(14) >>> frmt=_g.set_fcoform(14) >>> frmt '%.14e' >>> ofmt=_g.set_fcoform(frmt) >>> ofmt '%.14e' >>> _g.mpf(3.4) mpf('3.4e0') >>> print _g.mpf(3.4) 3.4 >>> for i in range(11,99): ... assert str(_g.mpf(i/10.0))==str(i/10.0) ... >>> a.digits(1) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: base must be either 0 or in the interval 2 ... 36 >>> a.digits(2,-1) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: digits must be >= 0 >>> a.digits(10,0,0,-1,2) ('123456', 3, 53) >>> saveprec=a.getrprec() >>> a.setprec(33) >>> a mpf('1.23456e2',33) >>> a.setprec(saveprec) >>> a.getrprec()==saveprec 1 >>> _g.fdigits(2.2e5, 0, 6, -10, 10) '220000.0' >>> _g.fdigits(2.2e-5, 0, 6, -10, 10) '0.000022' >>> _g.digits(_g.mpf(23.45)) '23' >>> _g.fbinary('pep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpf >>> ''' __test__['binio']=\ r''' >>> epsilon=_g.mpf(2)**-(a.getrprec()) >>> ba=a.binary() >>> a.reldiff(_g.mpf(ba,0,256)) <= epsilon 1 >>> len(ba) 18 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 8 53 0 0 0 1 0 0 0 123 116 188 106 126 249 219 34 209 >>> na=(-a).binary() >>> (-a).reldiff(_g.mpf(na,0,256)) <= epsilon 1 >>> na[0] == chr(ord(ba[0])|1) 1 >>> for bd,nd in zip(ba[1:],na[1:]): ... assert bd==nd >>> ia=(1/a).binary() >>> (1/a).reldiff(_g.mpf(ia,0,256)) <= epsilon 1 >>> _g.fbinary(0) '\x085\x00\x00\x00\x00\x00\x00\x00' >>> _g.fbinary(0.5) '\x085\x00\x00\x00\x00\x00\x00\x00\x80' >>> _g.fbinary(-0.5) '\t5\x00\x00\x00\x00\x00\x00\x00\x80' >>> _g.fbinary(-2.0) '\t5\x00\x00\x00\x01\x00\x00\x00\x02' >>> _g.fbinary(2.0) '\x085\x00\x00\x00\x01\x00\x00\x00\x02' >>> prec=_g.set_minprec(0) >>> junk=_g.set_minprec(prec) >>> a.getrprec()==prec 1 >>> b.getrprec()==prec 1 >>> _g.mpf(1.0).getrprec()==prec 1 >>> hash(_g.mpf(23.0))==hash(23) 1 >>> print _g.mpf('\004',0,256) 0.0 >>> long(a) 123L >>> long(-a) -123L >>> int(a) 123 >>> int(-a) -123 >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (mpf functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print print "Overall results for mpf:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_09_mpq.py --- # partial unit test for gmpy 0.9 mpq functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 0.9 r''' >>> dir(a) ['_copy', 'binary', 'denom', 'digits', 'numer', 'qdiv', 'sign'] >>> ''' import gmpy as _g, doctest,sys __test__={} a=_g.mpq('123/456') b=_g.mpq('789/123') __test__['elemop']=\ r''' >>> a+b mpq(41657,6232) >>> a-b mpq(-38295,6232) >>> a*b mpq(263,152) >>> a/b mpq(1681,39976) >>> b+a mpq(41657,6232) >>> b-a mpq(38295,6232) >>> b*a mpq(263,152) >>> b/a mpq(39976,1681) >>> a+1 mpq(193,152) >>> 1+a mpq(193,152) >>> a-1 mpq(-111,152) >>> 1-a mpq(111,152) >>> a*1 mpq(41,152) >>> 1*a mpq(41,152) >>> a/1 mpq(41,152) >>> 1/a mpq(152,41) >>> -a mpq(-41,152) >>> abs(-a) mpq(41,152) >>> _g.qsign(b-a) 1 >>> _g.qsign(b-b) 0 >>> _g.qsign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> an=a.numer(); ad=a.denom(); >>> an==0 or 1==a*_g.mpq(ad,an) 1 >>> bn=b.numer(); bd=b.denom(); >>> bn==0 or 1==b*_g.mpq(bd,bn) 1 >>> zn=z.numer(); zd=z.denom(); >>> zn==0 or 1==z*_g.mpq(zd,zn) 1 >>> (a+b) == _g.mpq(an*bd+ad*bn,ad*bd) 1 >>> (a+z) == _g.mpq(an*zd+ad*zn,ad*zd) 1 >>> (a+a) == _g.mpq(an*ad+ad*an,ad*ad) 1 >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpq(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpq(0) 1 >>> not a 0 >>> coerce(a,1) (mpq(41,152), mpq(1)) >>> coerce(1,a) (mpq(1), mpq(41,152)) >>> coerce(a,1.0) (mpq(41,152), mpq(1)) >>> coerce(a,_g.mpz(1)) (mpq(41,152), mpq(1)) >>> coerce(a,_g.mpf(1)) (mpq(41,152), mpq(1)) >>> a>1 0 >>> a>1.0 0 >>> a<1 1 >>> a<1.0 1 >>> a==1 0 >>> a==1.0 0 >>> cmp(a,1) -1 >>> cmp(1.0,a) 1 >>> long(1/a) 3L >>> long(-1/a) -3L >>> int(1/a) 3 >>> int(-1/a) -3 >>> ''' __test__['format']=\ r''' >>> str(a) '41/152' >>> repr(a) 'mpq(41,152)' >>> a==eval(repr(a),_g.__dict__) 1 >>> str(-a) '-41/152' >>> repr(-a) 'mpq(-41,152)' >>> (-a)==eval(repr(-a),_g.__dict__) 1 >>> _g.set_tagoff(0) 1 >>> a gmpy.mpq(41,152) >>> _g.set_tagoff(1) 0 >>> for i in range(1,7): ... for j in range(3,10): ... if _g.mpq(i,j) != _g.mpq("%d/%d"%(i,j)): ... print 'er1:',i,j; break ... aa=_g.mpq(i,j); ai=aa.numer(); aj=aa.denom() ... if aj!=1 and str(aa) != ("%d/%d"%(ai,aj)): ... print 'er2:',i,j,str(aa),("%d/%d"%(ai,aj)); break ... if aj==1 and str(aa) != ("%d"%ai): ... print 'er3:',i,j,str(aa),"%d"%ai; break ... if aj!=1 and repr(aa) != ("mpq(%d,%d)"%(ai,aj)): ... print 'er4:',i,j,repr(aa),("mpq(%d,%d)"%(ai,aj)); break ... if aj==1 and repr(aa) != ("mpq(%d)"%ai): ... print 'er5:',i,j,repr(aa),"mpq(%d)"%ai; break >>> fmo='_g.mpq('+a.numer().digits(16)+','+a.denom().digits(16)+')' >>> fmo '_g.mpq(0x29,0x98)' >>> eval(fmo)==a 1 >>> fmo='_g.mpq("'+a.numer().digits(30)+'/'+a.denom().digits(30)+'",30)' >>> fmo '_g.mpq("1b/52",30)' >>> eval(fmo)==a 1 >>> _g.qdigits(a,30) '1b/52' >>> a.digits(30) '1b/52' >>> _g.mpq(1000*1000*1000*1000L,23) mpq(1000000000000L,23) >>> _g.mpq(23,1000*1000*1000*1000L) mpq(23,1000000000000L) >>> _g.mpq(23L**10L,1000L**4L) mpq(41426511213649L,1000000000000L) >>> _g.qbinary('pep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpq >>> ''' __test__['binio']=\ r''' >>> ba=a.binary() >>> len(ba) 6 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 1 0 0 0 41 152 >>> _g.mpq(ba,256)==a 1 >>> ba == _g.qbinary(a) 1 >>> ba=(-a).binary() >>> len(ba) 6 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 1 0 0 128 41 152 >>> _g.mpq(ba,256)==-a 1 >>> hash(a)==hash(_g.mpf(a))==hash(float(a)) 1 >>> hash(b)==hash(_g.mpf(b))==hash(float(b)) 1 >>> hash(-a)==hash(-_g.mpf(a))==hash(-float(a)) 1 >>> hash(-b)==hash(-_g.mpf(b))==hash(-float(b)) 1 >>> ''' __test__['power']=\ r''' >>> _g.mpq(2,3)**3 mpq(8,27) >>> _g.mpq(8,27)**_g.mpq('2/3') mpq(4,9) >>> _g.mpq(2,3)**-3 mpq(27,8) >>> _g.mpq(8,27)**_g.mpq('-2/3') mpq(9,4) >>> print float(_g.mpf('0.2')**2) 0.04 >>> print float(_g.mpf('0.2')**-2) 25.0 >>> _g.mpq(3)**3 == _g.mpz(3)**3 1 >>> (a**-7) == 1/(a**7) 1 >>> (b**5) == 1/(b**-5) 1 >>> ''' __test__['qdiv']=\ r''' >>> _g.qdiv(12,2) mpz(6) >>> _g.qdiv(12,5) mpq(12,5) >>> a is a.qdiv() 1 >>> a is a.qdiv(1) 1 >>> a is a.qdiv(2) 0 >>> x=a.numer() >>> x is _g.qdiv(x) 1 >>> x is _g.qdiv(x,1) 1 >>> x is _g.qdiv(x,2) 0 >>> y=_g.mpq(4,1) >>> y is y.qdiv() 0 >>> y == y.qdiv() 1 >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (mpq functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with caching disabled" _g.set_qcache(0) sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_09_mpz.py --- # partial unit test for gmpy 0.9 mpz functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 0.9 r''' >>> filter(lambda x: not x.startswith('_'), dir(_g)) ['binary', 'bincoef', 'ceil', 'comb', 'denom', 'digits', 'divm', 'f2q', 'fac', 'fbinary', 'fdigits', 'fib', 'floor', 'fsign', 'fsqrt', 'gcd', 'gcdext', 'get_qcache', 'get_zcache', 'get_zconst', 'getbit', 'getprec', 'getrprec', 'gmp_version', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'lcm', 'legendre', 'lowbits', 'mpf', 'mpq', 'mpz', 'next_prime', 'numdigits', 'numer', 'popcount', 'qbinary', 'qdigits', 'qdiv', 'qsign', 'rand', 'reldiff', 'remove', 'root', 'scan0', 'scan1', 'set_callback', 'set_debug', 'set_fcoform', 'set_minprec', 'set_qcache', 'set_tagoff', 'set_zcache', 'set_zconst', 'setbit', 'sign', 'sqrt', 'sqrtrem', 'trunc', 'version'] >>> dir(a) ['_copy', 'binary', 'bincoef', 'comb', 'digits', 'getbit', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'legendre', 'lowbits', 'next_prime', 'numdigits', 'popcount', 'qdiv', 'remove', 'root', 'scan0', 'scan1', 'setbit', 'sign', 'sqrt', 'sqrtrem'] >>> ''' import gmpy as _g, doctest,sys __test__={} a=_g.mpz(123) b=_g.mpz(456) def factorize(x): r''' >>> factorize(a) [3, 41] >>> factorize(b) [2, 2, 2, 3, 19] >>> ''' import gmpy as _g savex=x prime=2 x=_g.mpz(x) factors=[] while x>=prime: newx,mult=x.remove(prime) if mult: factors.extend([int(prime)]*mult) x=newx prime=_g.next_prime(prime) for factor in factors: assert _g.is_prime(factor) from operator import mul assert reduce(mul, factors)==savex return factors __test__['elemop']=\ r''' >>> a+b mpz(579) >>> a-b mpz(-333) >>> a*b mpz(56088) >>> a/b mpz(0) >>> a%b mpz(123) >>> b+a mpz(579) >>> b-a mpz(333) >>> b*a mpz(56088) >>> b%a mpz(87) >>> divmod(a,b) (mpz(0), mpz(123)) >>> divmod(b,a) (mpz(3), mpz(87)) >>> -a mpz(-123) >>> abs(-a)==a 1 >>> pow(a,7) mpz(425927596977747L) >>> pow(a,7,b) mpz(99) >>> _g.sign(b-a) 1 >>> _g.sign(b-b) 0 >>> _g.sign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpz(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpz(0) 1 >>> not a 0 >>> coerce(a,1) (mpz(123), mpz(1)) >>> coerce(1,a) (mpz(1), mpz(123)) >>> coerce(a,1.0) (123.0, 1.0) >>> _g.mpz(3.14) mpz(3) >>> _g.mpz(_g.mpq(17,3)) mpz(5) >>> _g.mpz(23L) mpz(23) >>> _g.mpz(-23L) mpz(-23) >>> x=1000*1000*1000*1000L >>> _g.mpz(x) mpz(1000000000000L) >>> ''' __test__['bitops']=\ r''' >>> ~a mpz(-124) >>> a&b mpz(72) >>> a|b mpz(507) >>> a^b mpz(435) >>> a<<1 mpz(246) >>> a>>1 mpz(61) >>> a<<-1 Traceback (innermost last): File "<pyshell#42>", line 1, in ? a<<-1 ValueError: Pympz_lshift negative shift count >>> a>>-2 Traceback (innermost last): File "<pyshell#43>", line 1, in ? a>>-2 ValueError: Pympz_rshift negative shift count >>> a<<0 mpz(123) >>> a>>0 mpz(123) >>> a.popcount() 6 >>> _g.popcount(b) 4 >>> _g.popcount(-7) -1 >>> _g.popcount(0) 0 >>> a.hamdist(b) 6 >>> a.lowbits(5) mpz(27) >>> b.lowbits(5) mpz(8) >>> b.lowbits(5)==(b%32) 1 >>> a.lowbits(5)==(a%32) 1 >>> a.setbit(20) mpz(1048699) >>> a.setbit(0,0) mpz(122) >>> for i in range(8): ... print a.getbit(i), ... if i==7: print ... 1 1 0 1 1 1 1 0 >>> for i in range(10): ... print b.getbit(i), ... if i==9: print ... 0 0 0 1 0 0 1 1 1 0 >>> [a.scan0(j) for j in range(33)] [2, 2, 2, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] >>> [a.scan1(j) for j in range(10)] [0, 1, 3, 3, 4, 5, 6, None, None, None] >>> n=_g.mpz(-(7+6*16+5*256+7*4092)) >>> [n.scan0(j) for j in range(18)] [1, 1, 3, 3, 6, 6, 6, 8, 8, 10, 10, 12, 12, 13, 14, -1, None, None] >>> [n.scan1(j) for j in range(33)] [0, 2, 2, 4, 4, 5, 7, 7, 9, 9, 11, 11, 15, 15, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] >>> ''' __test__['format']=\ r''' >>> str(a) '123' >>> repr(a) 'mpz(123)' >>> hex(a) '0x7b' >>> oct(a) '0173' >>> _g.mpz('123') mpz(123) >>> _g.mpz('1001001011',2) mpz(587) >>> _g.mpz('1001001011',2).digits(2) '1001001011' >>> for i in range(2,37): ... print a.digits(i), ... if i%6==0: print ... 1111011 11120 1323 443 323 234 0173 146 123 102 a3 96 8b 83 0x7b 74 6f 69 63 5i 5d 58 53 4n 4j 4f 4b 47 43 3u 3r 3o 3l 3i 3f >>> print a.digits(37) Traceback (innermost last): File "<stdin>", line 1, in ? print a.digits(37) ValueError: base must be either 0 or in the interval 2 ... 36 >>> _g.set_tagoff(0) 1 >>> a gmpy.mpz(123) >>> _g.set_tagoff(1) 0 >>> _g.mpz('43') mpz(43) >>> _g.mpz('043') mpz(43) >>> _g.mpz('43',0) mpz(43) >>> _g.mpz('043',0) mpz(35) >>> _g.mpz('0x43',0) mpz(67) >>> _g.mpz('0x43') Traceback (innermost last): File "<pyshell#181>", line 1, in ? _g.mpz('0x43') ValueError: invalid digits >>> ''' __test__['binio']=\ r''' >>> ba=a.binary() >>> ba '{' >>> _g.mpz(ba,256) mpz(123) >>> _g.mpz(ba,256)==a 1 >>> _g.binary(123) '{' >>> z=_g.mpz('melancholy',256) >>> z mpz(573406620562849222387053L) >>> divmod(z,a) (mpz(4661842443600400182008L), mpz(69)) >>> for i in range(2,37): ... print i,z.numdigits(i), ... if i%6==0: print ... 2 79 3 50 4 40 5 35 6 31 7 29 8 27 9 25 10 24 11 23 12 23 13 22 14 21 15 21 16 20 17 20 18 19 19 19 20 19 21 18 22 18 23 18 24 18 25 18 26 17 27 17 28 17 29 17 30 17 31 16 32 16 33 16 34 16 35 16 36 16 >>> _g.numdigits(23) 2 >>> _g.numdigits(23,2) 5 >>> _g.numdigits(23,99) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: base must be either 0 or in the interval 2 ... 36 >>> hash(a) 123 >>> hash(b) 456 >>> hash(z) -791330233 >>> _g.mpz(_g.binary(-123),256) mpz(-123) >>> long(_g.mpz(-3)) -3L >>> ''' __test__['number']=\ r''' >>> print a.sqrt(), b.sqrt() 11 21 >>> print a.sqrtrem(), b.sqrtrem() (mpz(11), mpz(2)) (mpz(21), mpz(15)) >>> for i in range(5): ... print a.root(i+1),b.root(i+1) ... (mpz(123), 1) (mpz(456), 1) (mpz(11), 0) (mpz(21), 0) (mpz(4), 0) (mpz(7), 0) (mpz(3), 0) (mpz(4), 0) (mpz(2), 0) (mpz(3), 0) >>> a.is_square() 0 >>> a.is_power() 0 >>> _g.is_square(99*99) 1 >>> _g.is_square(99*99*99) 0 >>> _g.is_square(0) 1 >>> _g.is_square(-1) 0 >>> _g.is_power(99*99*99) 1 >>> _g.gcd(a,b) mpz(3) >>> _g.gcdext(a,b) (mpz(3), mpz(-63), mpz(17)) >>> _g.lcm(a,b) mpz(18696) >>> _g.fac(7) mpz(5040) >>> _g.fib(17) mpz(1597) >>> for i in range(10): ... print _g.bincoef(10,i) ... 1 10 45 120 210 252 210 120 45 10 >>> _g.divm(b,a,20) mpz(12) >>> _g.divm(a,b,100) Traceback (innermost last): File "<pyshell#184>", line 1, in ? _g.divm(a,b,100) ZeroDivisionError: not invertible >>> _g.divm(0,1,2) mpz(0) >>> a.invert(100) mpz(87) >>> b.invert(100) mpz(0) >>> _g.comb(3,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: binomial coefficient with negative k >>> _g.sqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.sqrtrem(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.remove(3,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: factor must be > 0 >>> _g.is_prime(3,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: repetition count for is_prime must be positive >>> _g.jacobi(10,3) 1 >>> _g.jacobi(10,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: jacobi's y must be odd prime > 0 >>> _g.legendre(10,3) 1 >>> _g.legendre(10,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: legendres's y must be odd and > 0 >>> _g.kronecker(10,3) 1 >>> _g.kronecker(10,-3) 1 >>> a=1000000L**2 >>> b=a+1 >>> _g.jacobi(a,b) 1 >>> _g.legendre(a,b) 1 >>> _g.kronecker(a,b) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Either arg in Kronecker must fit in an int >>> f=_g.mpf(3.3) >>> f.setprec(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be >=0 >>> _g.rand('init',-1) >>> _g.rand('init',-7) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: size must be in 1..128 >>> _g.rand('init',200) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: size must be in 1..128 >>> _g.rand('qual') 32 >>> _g.rand('floa',-7) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: 'floa' needs arg>=0 ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (mpz functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with caching disabled" _g.set_zcache(0) _g.set_zconst(0,0) sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_09_rnd.py --- # partial unit test for gmpy 0.9 rand functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 0.9 r''' >>> r <built-in function rand> >>> ''' import gmpy as _g, doctest,sys __test__={} r = _g.rand __test__['rand']=\ r''' >>> r('error',1,2,3) Traceback (most recent call last): File "<string>", line 1, in ? TypeError: function takes exactly 2 arguments (4 given) >>> r('save') Traceback (most recent call last): File "<string>", line 1, in ? RuntimeError: can't save before init >>> r('init',20) >>> r('unkn',99) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: unknown option 'unkn' >>> r('seed',1234) >>> for i in range(5): ... print r('next',100), ... if i==4: print ... 21 75 63 28 27 >>> alis=list("proktelnu") >>> for i in range(10): ... r('shuf',alis) ... print ''.join(alis) ... rtoulpnke eoturlknp plnuetokr ekoprulnt kpoutnrel rutoneklp ukeptnorl onkrlpteu lknteropu enrkutlpo >>> sav=r('save') >>> print sav 774447212137 >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... elnuortpk enutolpkr eropulntk plroutenk ekonrtplu >>> r('seed',sav) >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... epkruotln ekrtuplno eoulrpktn lpourtekn enukotlpr >>> r('seed',sav) >>> for i in range(3): ... print float(r('floa')) ... 0.44833278656 0.547296524048 0.895370483398 >>> r('seed',sav) >>> for i in range(3): ... print float(r('floa',6)) ... 0.484375 0.90625 0.75 >>> r('seed',sav) >>> for i in range(3): ... print _g.f2q(r('floa',6),-6) ... 15/31 9/10 3/4 >>> r('seed',sav) >>> for i in range(3): ... print _g.f2q(r('floa',6)) ... 31/64 29/32 3/4 >>> r('seed',sav) >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... elnorutpk enotrlpku eurpolntk plurotenk ekrnutplo >>> r('shuf','astring') Traceback (most recent call last): File "<string>", line 1, in ? TypeError: object doesn't support item assignment >>> r('shuf',23) Traceback (most recent call last): File "<string>", line 1, in ? TypeError: 'shuf' needs mutable sequence >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (rand functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache() ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print print "Overall results for rnd:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) |
From: Alex M. <al...@us...> - 2002-03-05 11:05:14
|
Update of /cvsroot/gmpy/gmpy/doc In directory usw-pr-cvs1:/tmp/cvs-serv6547/doc Modified Files: gmpydoc.txt index.html Log Message: Updates for gmpy 0.9.0c. Index: gmpydoc.txt =================================================================== RCS file: /cvsroot/gmpy/gmpy/doc/gmpydoc.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** gmpydoc.txt 1 Mar 2002 08:19:44 -0000 1.2 --- gmpydoc.txt 5 Mar 2002 11:05:11 -0000 1.3 *************** *** 34,37 **** --- 34,39 ---- Minor editing for version 0.9b (2002/02/28). + Minor editing for version 0.9c (2002/03/05). + *Acknowledgments* *************** *** 53,57 **** *Installation and testing* ! Pre-requisites: Python 2, GMP 4.0.1 (see later for Win32). To build gmpy from sources, unpack the sources zipfile --- 55,65 ---- *Installation and testing* ! Pre-requisites: Python 2.2, GMP 4.0.1 (see later for Win32). ! GMP 3.1.1 is still supported for the moment (but will ! be phased out soon) -- testing and bugfixes only for ! bugs reproducible in GMP 4 (no more workarounds for ! GMP 3 - only bugs). Not yet any GMP 4 only functionality. ! No known use of Python 2.2-only functionality yet, but ! no support/bugfixes planned for older Python releases. To build gmpy from sources, unpack the sources zipfile *************** *** 72,75 **** --- 80,91 ---- 6 is found at: ftp://ftp.whiterose.net/pub/lundman. + GMP 4 for Windows has not been checked out yet. Take care + when installing GMP 4 that an older GMP 3 doesn't keep + being used, e.g. on Linux if you have a system-installed + GMP 3 in /usr/lib and install the newer GMP 4 by default + (it goes into /usr/local/lib, and depending on various + details of your system configuration the /usr/lib version + may keep being used instead). + Distutils are not yet supported for the pre-built gmpy.pyd for windows, that comes in the gmpy-win32-binary-08.zip *************** *** 91,110 **** where you unpacked the sources, run at the command prompt: ! python gmpy_test_08.py Expected output is something like (details may differ!): """ ! Unit tests for gmpy 0.8 pre-alpha ! on Python 2.0 (#8, Oct 16 2000, 17:27:58) [MSC 32 bit (Intel)] ! Testing gmpy 0.8.0c (GMP 3.1.1), default caching (20, 20, -2..11) ! gmpy_test_08_cvr 120 tests, 0 failures ! gmpy_test_08_rnd 21 tests, 0 failures ! gmpy_test_08_mpf 137 tests, 0 failures ! gmpy_test_08_mpq 122 tests, 0 failures ! gmpy_test_08_mpz 156 tests, 0 failures ! 26 items passed all tests: ! [26 lines snipped] ! 556 tests in 26 items. ! 556 passed and 0 failed. Test passed. """ --- 107,127 ---- where you unpacked the sources, run at the command prompt: ! python gmpy_test_09.py Expected output is something like (details may differ!): """ ! Unit tests for gmpy 0.9 pre-alpha ! on Python 2.2 (#1, Dec 23 2001, 20:09:01) ! [GCC 2.96 20000731 (Mandrake Linux 8.1 2.96-0.62mdk)] ! Testing gmpy 0.9.0c (GMP 4.0.1), default caching (20, 20, -2..11) ! gmpy_test_09_cvr 262 tests, 0 failures ! gmpy_test_09_rnd 26 tests, 0 failures ! gmpy_test_09_mpf 140 tests, 0 failures ! gmpy_test_09_mpq 242 tests, 0 failures ! gmpy_test_09_mpz 310 tests, 0 failures ! 25 items passed all tests: ! [ 25 lines snipped ] ! 980 tests in 25 items. ! 980 passed and 0 failed. Test passed. """ *************** *** 113,124 **** that each of the various modules listed at the start can also be run independently, if so desired: ! python gmpy_test_08_mpq.py ! python gmpy_test_08_mpz.py and so on, expecting output analogous to the above example. The key issue is the 'Test passed' line at the end of each run! ! *PLEASE* report any failures to gmpy's maintainer, with ! any details you can supply on your machine, on your OS, ! and on your installation of GMP, gmpy, Python 2, and any other relevant issue (your C/C++ compiler & libraries, &c). *THANKS* in advance -- bug reporting and feedback is your --- 130,141 ---- that each of the various modules listed at the start can also be run independently, if so desired: ! python gmpy_test_09_mpq.py ! python gmpy_test_09_mpz.py and so on, expecting output analogous to the above example. The key issue is the 'Test passed' line at the end of each run! ! *PLEASE* report any failures to gmpy's maintainers, with ! any details you can supply on your machine, on your OS, and ! on your installation of GMP 4, gmpy 0.9, Python 2.2, and any other relevant issue (your C/C++ compiler & libraries, &c). *THANKS* in advance -- bug reporting and feedback is your *************** *** 137,141 **** See GMP documentation for general descriptions of them! ! GNU MP Home Page: http://www.swox.com/gmp/ Licensing: since GMP is distributed under the LGPL, so, --- 154,158 ---- See GMP documentation for general descriptions of them! ! GNU MP Home Page: http://swox.com/gmp/ Licensing: since GMP is distributed under the LGPL, so, Index: index.html =================================================================== RCS file: /cvsroot/gmpy/gmpy/doc/index.html,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** index.html 1 Mar 2002 08:19:44 -0000 1.2 --- index.html 5 Mar 2002 11:05:11 -0000 1.3 *************** *** 14,19 **** <BODY> <FONT SIZE=-1> ! Last updated on: 2002, Feb 28; ! for GMPY release: 0.9b pre-alpha <A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=13335&type=1" --- 14,19 ---- <BODY> <FONT SIZE=-1> ! Last updated on: 2002, Mar 5; ! for GMPY release: 0.9.0c pre-alpha <A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=13335&type=1" *************** *** 65,68 **** --- 65,70 ---- will later also be considered for inclusion in gmpy (either within the same module, or as a further, separate add-on module). + Rooting for MPFR to be merged with GMP so we can avoid some + awkwardness (hopefully by GMP 4.1 later in Spring 2002...!). <H2>Mutability... but <u>not</u> for now</H2> *************** *** 89,93 **** <H1>Project Status and near-future plans</H1> The gmpy module's early, pre-alpha releases (latest current release ! as of 2002/02/28: 0.9b) are already available for download in both source and Windows-binary form. They expose all of the mpz, mpq and mpf functionality that was already available in GMP 3.1, and --- 91,95 ---- <H1>Project Status and near-future plans</H1> The gmpy module's early, pre-alpha releases (latest current release ! as of 2002/03/05: 0.9.0c) are available for download in both source and Windows-binary form. They expose all of the mpz, mpq and mpf functionality that was already available in GMP 3.1, and *************** *** 98,105 **** <p> On most platforms, you will need to separately procure and install ! the GMP library itself to be able to build and use GMPY (note that 4.0.1 or better is needed; take care: some Linux releases come bundled with <strong>older</strong> GMP versions, such as GMP 3, and you may ! have to install the latest GMP version instead!). <p> The exception to this need is under (32-bit) Windows, where --- 100,108 ---- <p> On most platforms, you will need to separately procure and install ! the GMP library itself to be able to build and use GMPY. Note that 4.0.1 or better is needed; take care: some Linux releases come bundled with <strong>older</strong> GMP versions, such as GMP 3, and you may ! have to install the latest GMP version instead -- beware also of ! /usr/lib vs /usr/local/lib issues. <p> The exception to this need is under (32-bit) Windows, where *************** *** 108,123 **** are traditionally hard to come by. <p> ! We started the GMPY project using a VC++ port of GMP.LIB "just found ! on the net", but have currently switched to the port by Jorgen Lundman found at <a href="ftp://ftp.whiterose.net/pub/lundman/"> ! ftp://ftp.whiterose.net/pub/lundman/</a> (bravo Lundy!). Windows users ! do not need to download from Jorgen's site: a separate 'binary library' ! package, including Lundy's ports of GMP.LIB and GMP.H, is made available ! on the gmpy project's ftp-space for Windows/VC++6 users that do want to ! re-build the gmpy module from sources; and also, another separate 'binary ! module' package is supplied, containing only the pre-built GMPY.PYD, ! for those who do <b>not</b> want to re-build from sources. ! For GMP 4.0, the plan is to use the native support it offers for ! the Windows platform. <p> <b>Do</b> note, however, that <b>all</b> gmpy users should download the --- 111,127 ---- are traditionally hard to come by. <p> ! We started the GMPY project using a VC++ port of GMP.LIB "just found on ! the net", but have currently switched to the port by Jorgen Lundman found at <a href="ftp://ftp.whiterose.net/pub/lundman/"> ! ftp://ftp.whiterose.net/pub/lundman/</a> (bravo Lundy!). Windows ! users do not need to download from Jorgen's site: a separate 'binary ! library' package, including Lundy's ports of GMP.LIB and GMP.H, is made ! available on the gmpy project's ftp-space for Windows/VC++6 users that ! do want to re-build the gmpy module from sources; and also, another ! separate 'binary module' package is supplied, containing only the ! pre-built GMPY.PYD, for those who do <b>not</b> want to re-build from ! sources. For GMP 4.0, the plan is to use the native support it offers ! for the Windows platform, but this has not yet been explored in ! detail. <p> <b>Do</b> note, however, that <b>all</b> gmpy users should download the *************** *** 146,160 **** <p> Unit tests are not considered a weak point any more; the almost-1000 ! unit-tests now being run provide a decent cover of 92+% SLOC for ! gmpy.c, up from 72% in 0.7. The non-covered SLOCs (about 170 ! of gmpy.c's current 2370) are mostly disaster-tests to handle ! out-of-memory situations, and code providing optional debugging ! output (for debugging the gmpy module -- see the set_debug facility), ! with a smattering of 'defensive programming' cases (to handle ! situations that 'should never happen, but'...) and some cases of the ! new experimental 'callbacks' facility (mostly provided for the specific ! use of PySymbolic, and intended to be tested by that package). ! We'll have to do better, eventually, but, for now, this can ! be considered OK for an alpha-release. <p> In the attempt to make gmpy as useful as can be for both stand-alone --- 150,163 ---- <p> Unit tests are not considered a weak point any more; the almost-1000 ! unit-tests now being run provide a decent cover of 93+% SLOC for gmpy.c, ! up from 72% in 0.7. The non-covered SLOCs (about 170 of gmpy.c's ! current 2600) are mostly disaster-tests to handle out-of-memory ! situations, code providing optional debugging output (for debugging the ! gmpy module -- see the set_debug facility), a smattering of 'defensive ! programming' cases (to handle situations that 'should never happen, ! but'...) and some cases of the new experimental 'callbacks' facility ! (mostly provided for the specific use of PySymbolic, and intended to be ! tested by that package). We'll have to do better, eventually, but, for ! now, this can be considered OK for an alpha-release. <p> In the attempt to make gmpy as useful as can be for both stand-alone *************** *** 175,179 **** formatted documentation; more timing-measurement scripts and usage-examples. Some of the currently ! experimental 'callbacks' will also be removed, as having been proven unnecessary. All relevant GMP 4 functionality will be exposed. --- 178,182 ---- formatted documentation; more timing-measurement scripts and usage-examples. Some of the currently ! experimental 'callbacks' will also be removed, having been proven unnecessary. All relevant GMP 4 functionality will be exposed. *************** *** 181,184 **** --- 184,190 ---- The current plans forecast all of this will be completed on, or before, May 1, 2002 (give or take about 10 days). + But our predictions have proved optimistic in the past, + so, don't hold your breath (pitching in and helping it + happen, on the other hand, _might_ be advisable:-). <p> <A HREF="http://sourceforge.net/projects/gmpy/">Project |
From: Alex M. <al...@us...> - 2002-03-05 11:05:14
|
Update of /cvsroot/gmpy/gmpy/src In directory usw-pr-cvs1:/tmp/cvs-serv6547/src Modified Files: gmpy.c Log Message: Updates for gmpy 0.9.0c. Index: gmpy.c =================================================================== RCS file: /cvsroot/gmpy/gmpy/src/gmpy.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** gmpy.c 1 Mar 2002 08:19:44 -0000 1.2 --- gmpy.c 5 Mar 2002 11:05:11 -0000 1.3 *************** *** 96,100 **** * * 0.9b: ! * support GMP 4 * */ --- 96,103 ---- * * 0.9b: ! * support GMP 4 (but added no GMP4-only functionality yet) ! * ! * 0.9c: ! * updated tests to 0.9, better coverage * */ *************** *** 813,822 **** s=PyString_Format(options.fcoform, tuple); Py_DECREF(tuple); ! if(options.debug) { fprintf(stderr,"f2mp(%s,%f->%s)\n", PyString_AsString(options.fcoform), PyFloat_AsDouble(f), s?PyString_AsString(s):"<NoString>"); ! } if(!s) return 0; newob = str2mpf(s, 10, bits); --- 816,825 ---- s=PyString_Format(options.fcoform, tuple); Py_DECREF(tuple); ! if(options.debug) fprintf(stderr,"f2mp(%s,%f->%s)\n", PyString_AsString(options.fcoform), PyFloat_AsDouble(f), s?PyString_AsString(s):"<NoString>"); ! if(!s) return 0; newob = str2mpf(s, 10, bits); *************** *** 1996,2002 **** newob = long2mpq(obj); } ! if(options.debug) { fprintf(stderr,"any2mpq(%p)->%p\n", obj, newob); ! } return newob; } --- 1999,2005 ---- newob = long2mpq(obj); } ! if(options.debug) fprintf(stderr,"any2mpq(%p)->%p\n", obj, newob); ! return newob; } *************** *** 2021,2027 **** newob = float2mpz(obj); } ! if(options.debug) { fprintf(stderr,"any2mpz(%p)->%p\n", obj, newob); ! } return newob; } --- 2024,2030 ---- newob = float2mpz(obj); } ! if(options.debug) fprintf(stderr,"any2mpz(%p)->%p\n", obj, newob); ! return newob; } *************** *** 2050,2057 **** newob = long2mpf(obj, bits); } ! if(options.debug) { fprintf(stderr, "anynum2mpf(%p,%d)->%p (%d)\n", obj, bits, newob, newob?newob->rebits:-1); ! } return newob; } --- 2053,2060 ---- newob = long2mpf(obj, bits); } ! if(options.debug) fprintf(stderr, "anynum2mpf(%p,%d)->%p (%d)\n", obj, bits, newob, newob?newob->rebits:-1); ! return newob; } *************** *** 2065,2071 **** { PympzObject* newob = anynum2mpz(arg); ! if(options.debug) { fprintf(stderr, "mpz_conv_arg(%p)->%p\n", arg, newob); ! } if(newob) { *ptr = (PyObject*)newob; --- 2068,2074 ---- { PympzObject* newob = anynum2mpz(arg); ! if(options.debug) fprintf(stderr, "mpz_conv_arg(%p)->%p\n", arg, newob); ! if(newob) { *ptr = (PyObject*)newob; *************** *** 2085,2091 **** { PympqObject* newob = anynum2mpq(arg); ! if(options.debug) { fprintf(stderr, "mpq_conv_arg(%p)->%p\n", arg, newob); ! } if(newob) { *ptr = (PyObject*)newob; --- 2088,2094 ---- { PympqObject* newob = anynum2mpq(arg); ! if(options.debug) fprintf(stderr, "mpq_conv_arg(%p)->%p\n", arg, newob); ! if(newob) { *ptr = (PyObject*)newob; *************** *** 2105,2111 **** { PympfObject* newob = anynum2mpf(arg,0); ! if(options.debug) { fprintf(stderr, "mpf_conv_arg(%p)->%p\n", arg, newob); ! } if(newob) { *ptr = (PyObject*)newob; --- 2108,2114 ---- { PympfObject* newob = anynum2mpf(arg,0); ! if(options.debug) fprintf(stderr, "mpf_conv_arg(%p)->%p\n", arg, newob); ! if(newob) { *ptr = (PyObject*)newob; *************** *** 2390,2397 **** if(starting_bit > maxbit) { int sig = mpz_sgn(Pympz_AS_MPZ(self)); ! if(options.debug) { fprintf(stderr,"scan0 start=%ld max=%ld sig=%d\n", starting_bit, maxbit, sig); ! } if(sig<0) s = Py_BuildValue(""); --- 2393,2400 ---- if(starting_bit > maxbit) { int sig = mpz_sgn(Pympz_AS_MPZ(self)); ! if(options.debug) fprintf(stderr,"scan0 start=%ld max=%ld sig=%d\n", starting_bit, maxbit, sig); ! if(sig<0) s = Py_BuildValue(""); *************** *** 2438,2445 **** if(starting_bit >= maxbit) { int sig = mpz_sgn(Pympz_AS_MPZ(self)); ! if(options.debug) { fprintf(stderr,"scan1 start=%ld max=%ld sig=%d\n", starting_bit, maxbit, sig); ! } if(sig>=0) s = Py_BuildValue(""); --- 2441,2448 ---- if(starting_bit >= maxbit) { int sig = mpz_sgn(Pympz_AS_MPZ(self)); ! if(options.debug) fprintf(stderr,"scan1 start=%ld max=%ld sig=%d\n", starting_bit, maxbit, sig); ! if(sig>=0) s = Py_BuildValue(""); *************** *** 3067,3074 **** } } ! if(options.debug) { fprintf(stderr, "Pygmpy_mpz: created mpz = %ld\n", mpz_get_si(newob->z)); ! } return (PyObject *) newob; --- 3070,3077 ---- } } ! if(options.debug) fprintf(stderr, "Pygmpy_mpz: created mpz = %ld\n", mpz_get_si(newob->z)); ! return (PyObject *) newob; |
From: Alex M. <al...@us...> - 2002-03-05 11:05:13
|
Update of /cvsroot/gmpy/gmpy In directory usw-pr-cvs1:/tmp/cvs-serv6547 Modified Files: setup.py Log Message: Updates for gmpy 0.9.0c. Index: setup.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/setup.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** setup.py 1 Mar 2002 08:19:44 -0000 1.2 --- setup.py 5 Mar 2002 11:05:10 -0000 1.3 *************** *** 11,15 **** setup (name = "gmpy", ! version = "0.9", description = "GMP-3 to Python-2 interface", maintainer = "Alex Martelli", --- 11,15 ---- setup (name = "gmpy", ! version = "0.9.0c", description = "GMP-3 to Python-2 interface", maintainer = "Alex Martelli", |
From: Alex M. <al...@us...> - 2002-03-01 08:19:47
|
Update of /cvsroot/gmpy/gmpy/test In directory usw-pr-cvs1:/tmp/cvs-serv27677/test Modified Files: gmpy_test_08_mpz.py Log Message: Updated towards 0.9b fixing a few minor code issues and the docs. Not yet able to build with gmp 4 (probably misinstalled gmp?). Index: gmpy_test_08_mpz.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/test/gmpy_test_08_mpz.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** gmpy_test_08_mpz.py 24 Jan 2002 14:20:14 -0000 1.1.1.1 --- gmpy_test_08_mpz.py 1 Mar 2002 08:19:44 -0000 1.2 *************** *** 4,8 **** r''' >>> filter(lambda x: not x.startswith('_'), dir(_g)) ! ['binary', 'bincoef', 'ceil', 'comb', 'denom', 'digits', 'divm', 'f2q', 'fac', 'fbinary', 'fdigits', 'fib', 'floor', 'fsign', 'fsqrt', 'gcd', 'gcdext', 'get_qcache', 'get_zcache', 'get_zconst', 'getbit', 'getprec', 'getrprec', 'gmp_version', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'lcm', 'legendre', 'lowbits', 'mpf', 'mpq', 'mpz', 'next_prime', 'numdigits', 'numer', 'popcount', 'qbinary', 'qdigits', 'qdiv', 'qsign', 'rand', 'reldiff', 'remove', 'root', 'scan0', 'scan1', 'set_callback', 'set_debug', 'set_fcoform', 'set_minprec', 'set_qcache', 'set_tagoff', 'set_zcache', 'set_zconst', 'setbit', 'sign', 'sqrt', 'sqrtrem', 'trunc', 'version'] >>> dir(a) ['_copy', 'binary', 'bincoef', 'comb', 'digits', 'getbit', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'legendre', 'lowbits', 'next_prime', 'numdigits', 'popcount', 'qdiv', 'remove', 'root', 'scan0', 'scan1', 'setbit', 'sign', 'sqrt', 'sqrtrem'] --- 4,8 ---- r''' >>> filter(lambda x: not x.startswith('_'), dir(_g)) ! ['binary', 'bincoef', 'ceil', 'comb', 'denom', 'digits', 'divm', 'f2q', 'fac', 'fbinary', 'fdigits', 'fib', 'floor', 'fsign', 'fsqrt', 'gcd', 'gcdext', 'get_qcache', 'get_zcache', 'get_zconst', 'getbit', 'getprec', 'getrprec', 'gmp_version', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'lcm', 'legendre', 'lowbits', 'mpf', 'mpq', 'mpz', 'next_prime', 'numdigits', 'numer', 'pi', 'popcount', 'qbinary', 'qdigits', 'qdiv', 'qsign', 'rand', 'reldiff', 'remove', 'root', 'scan0', 'scan1', 'set_callback', 'set_debug', 'set_fcoform', 'set_minprec', 'set_qcache', 'set_tagoff', 'set_zcache', 'set_zconst', 'setbit', 'sign', 'sqrt', 'sqrtrem', 'trunc', 'version'] >>> dir(a) ['_copy', 'binary', 'bincoef', 'comb', 'digits', 'getbit', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'legendre', 'lowbits', 'next_prime', 'numdigits', 'popcount', 'qdiv', 'remove', 'root', 'scan0', 'scan1', 'setbit', 'sign', 'sqrt', 'sqrtrem'] |
From: Alex M. <al...@us...> - 2002-03-01 08:19:47
|
Update of /cvsroot/gmpy/gmpy/src In directory usw-pr-cvs1:/tmp/cvs-serv27677/src Modified Files: gmpy.c Log Message: Updated towards 0.9b fixing a few minor code issues and the docs. Not yet able to build with gmp 4 (probably misinstalled gmp?). Index: gmpy.c =================================================================== RCS file: /cvsroot/gmpy/gmpy/src/gmpy.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** gmpy.c 24 Jan 2002 14:19:21 -0000 1.1.1.1 --- gmpy.c 1 Mar 2002 08:19:44 -0000 1.2 *************** *** 5,9 **** * Rewritten by Niels Möller, May 1996 * ! * Version for GMP-3, Python-2, with support for MSVC++6. * addition of mpf's, &c: Alex Martelli (al...@ya..., Nov 2000). * --- 5,9 ---- * Rewritten by Niels Möller, May 1996 * ! * Version for GMP-4, Python-2, with support for MSVC++6. * addition of mpf's, &c: Alex Martelli (al...@ya..., Nov 2000). * *************** *** 95,98 **** --- 95,101 ---- * fixed gcc warnings reported by K. Briggs * + * 0.9b: + * support GMP 4 + * */ #include <assert.h> *************** *** 316,320 **** last_try_self(const char* nm, int min, int max, PyObject* args, PyObject* self) { ! PyObject *funky_arg, *extype, *exvalue, *extb; int i; int tlen = PyTuple_Size(args); --- 319,323 ---- last_try_self(const char* nm, int min, int max, PyObject* args, PyObject* self) { ! PyObject *funky_arg=0, *extype, *exvalue, *extb; int i; int tlen = PyTuple_Size(args); *************** *** 327,331 **** break; } ! if(i>=tlen) { PyErr_Restore(extype, exvalue, extb); return 0; --- 330,334 ---- break; } ! if(i>=tlen || !funky_arg) { PyErr_Restore(extype, exvalue, extb); return 0; *************** *** 5129,5133 **** PympzObject *resob = Pympz_new(); if(resob) { ! mpz_set(resob->z, randstate->seed); result = (PyObject*)resob; } --- 5132,5136 ---- PympzObject *resob = Pympz_new(); if(resob) { ! mpz_set(resob->z, randstate->_mp_seed); result = (PyObject*)resob; } *************** *** 5292,5296 **** { "fac", Pygmpy_fac, 1, doc_fac }, { "fib", Pygmpy_fib, 1, doc_fib }, ! { "pi", Pygmpy_pi, 1 }, { "rand", Pygmpy_rand, 1, doc_rand }, --- 5295,5299 ---- { "fac", Pygmpy_fac, 1, doc_fac }, { "fib", Pygmpy_fib, 1, doc_fib }, ! { "pi", Pygmpy_pi, 1, doc_pi }, { "rand", Pygmpy_rand, 1, doc_rand }, |
From: Alex M. <al...@us...> - 2002-03-01 08:19:47
|
Update of /cvsroot/gmpy/gmpy/doc In directory usw-pr-cvs1:/tmp/cvs-serv27677/doc Modified Files: gmpydoc.txt index.html Log Message: Updated towards 0.9b fixing a few minor code issues and the docs. Not yet able to build with gmp 4 (probably misinstalled gmp?). Index: gmpydoc.txt =================================================================== RCS file: /cvsroot/gmpy/gmpy/doc/gmpydoc.txt,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** gmpydoc.txt 24 Jan 2002 14:17:35 -0000 1.1.1.1 --- gmpydoc.txt 1 Mar 2002 08:19:44 -0000 1.2 *************** *** 32,35 **** --- 32,37 ---- Very minor editing for version 0.9 (2001/01/25). + Minor editing for version 0.9b (2002/02/28). + *Acknowledgments* *************** *** 51,55 **** *Installation and testing* ! Pre-requisites: Python 2, GMP 3.1.1 (see later for Win32). To build gmpy from sources, unpack the sources zipfile --- 53,57 ---- *Installation and testing* ! Pre-requisites: Python 2, GMP 4.0.1 (see later for Win32). To build gmpy from sources, unpack the sources zipfile *************** *** 62,66 **** build and install the gmpy module for you. ! On Unix, GMP 3.1.1 must have been previously and separately installed; on Win32, the gmp.lib and gmp.h supplied (in the gmpy-win32 package, only; file gmpy-win32-library-06.zip, --- 64,68 ---- build and install the gmpy module for you. ! On Unix, GMP 4.0.1 must have been previously and separately installed; on Win32, the gmp.lib and gmp.h supplied (in the gmpy-win32 package, only; file gmpy-win32-library-06.zip, *************** *** 72,77 **** Distutils are not yet supported for the pre-built gmpy.pyd for windows, that comes in the gmpy-win32-binary-08.zip ! file -- just move the gmpy.pyd it contains to c:\Python20 ! (or wherever you have your Python 2.0 installation). The sources zipfile also contains this file (gmpydoc.txt), --- 74,79 ---- Distutils are not yet supported for the pre-built gmpy.pyd for windows, that comes in the gmpy-win32-binary-08.zip ! file -- just move the gmpy.pyd it contains to c:\Python22 ! (or wherever you have your Python 2.2 installation). The sources zipfile also contains this file (gmpydoc.txt), *************** *** 129,133 **** gmpy exposes to Python three types of numbers that are ! implemented in GMP 3: mpz unlimited-precision integers mpq unlimited-precision rationals --- 131,135 ---- gmpy exposes to Python three types of numbers that are ! implemented in both GMP 3 and GMP 4: mpz unlimited-precision integers mpq unlimited-precision rationals Index: index.html =================================================================== RCS file: /cvsroot/gmpy/gmpy/doc/index.html,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** index.html 24 Jan 2002 14:17:38 -0000 1.1.1.1 --- index.html 1 Mar 2002 08:19:44 -0000 1.2 *************** *** 14,19 **** <BODY> <FONT SIZE=-1> ! Last updated on: 2001, Jan 25; ! for GMPY release: 0.9 pre-alpha <A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=13335&type=1" --- 14,19 ---- <BODY> <FONT SIZE=-1> ! Last updated on: 2002, Feb 28; ! for GMPY release: 0.9b pre-alpha <A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=13335&type=1" *************** *** 47,52 **** The first GMPY goal is to develop this module into a complete exposure of MPZ, MPF (floating-point), and MPQ (rational) ! functionality of current GMP (release 3.1), that will fully ! support current Python (release 2.0) and its handy 'distutils' (and also support a "C API" allowing some level of interoperation with other C-written extension modules for Python). --- 47,52 ---- The first GMPY goal is to develop this module into a complete exposure of MPZ, MPF (floating-point), and MPQ (rational) ! functionality of current GMP (release 4.0), that will fully ! support current Python (release 2.2) and its handy 'distutils' (and also support a "C API" allowing some level of interoperation with other C-written extension modules for Python). *************** *** 67,71 **** <H2>Mutability... but <u>not</u> for now</H2> ! Early tests have shown that supporting Python 2.0's "in-place operation" functionality (by making MPZ, MPF and MPQ Python objects <b>mutable</b>) could offer a substantial performance boost. --- 67,71 ---- <H2>Mutability... but <u>not</u> for now</H2> ! Early tests have shown that supporting Python 2's "in-place operation" functionality (by making MPZ, MPF and MPQ Python objects <b>mutable</b>) could offer a substantial performance boost. *************** *** 89,105 **** <H1>Project Status and near-future plans</H1> The gmpy module's early, pre-alpha releases (latest current release ! as of 2001/01/25: 0.9) are already available for download in both source and Windows-binary form. They expose all of the mpz, mpq ! and mpf functionality available in GMP 3.1, and most of the ! random-number generation functionality (there are no current plans ! to extend gmpy to expose other such functionality, although the ! currently experimental way that it is architected is subject to ! likely future changes). <p> On most platforms, you will need to separately procure and install the GMP library itself to be able to build and use GMPY (note that ! 3.1.1 or better is needed; take care: some Linux releases come bundled ! with <strong>older</strong> GMP versions, such as GMP 2, and you may ! have to uninstall these and then install the latest GMP version!). <p> The exception to this need is under (32-bit) Windows, where --- 89,105 ---- <H1>Project Status and near-future plans</H1> The gmpy module's early, pre-alpha releases (latest current release ! as of 2002/02/28: 0.9b) are already available for download in both source and Windows-binary form. They expose all of the mpz, mpq ! and mpf functionality that was already available in GMP 3.1, and ! most of the random-number generation functionality (there are no ! current plans to extend gmpy to expose other such functionality, ! although the currently experimental way that it is architected is ! subject to likely future changes). <p> On most platforms, you will need to separately procure and install the GMP library itself to be able to build and use GMPY (note that ! 4.0.1 or better is needed; take care: some Linux releases come bundled ! with <strong>older</strong> GMP versions, such as GMP 3, and you may ! have to install the latest GMP version instead!). <p> The exception to this need is under (32-bit) Windows, where *************** *** 118,121 **** --- 118,123 ---- module' package is supplied, containing only the pre-built GMPY.PYD, for those who do <b>not</b> want to re-build from sources. + For GMP 4.0, the plan is to use the native support it offers for + the Windows platform. <p> <b>Do</b> note, however, that <b>all</b> gmpy users should download the *************** *** 174,181 **** scripts and usage-examples. Some of the currently experimental 'callbacks' will also be removed, as ! having been proven unnecessary. <p> The current plans forecast all of this will be completed ! on, or before, March 1, 2000 (give or take about 10 days). <p> <A HREF="http://sourceforge.net/projects/gmpy/">Project --- 176,184 ---- scripts and usage-examples. Some of the currently experimental 'callbacks' will also be removed, as ! having been proven unnecessary. All relevant GMP 4 ! functionality will be exposed. <p> The current plans forecast all of this will be completed ! on, or before, May 1, 2002 (give or take about 10 days). <p> <A HREF="http://sourceforge.net/projects/gmpy/">Project |
From: Alex M. <al...@us...> - 2002-03-01 08:19:47
|
Update of /cvsroot/gmpy/gmpy In directory usw-pr-cvs1:/tmp/cvs-serv27677 Modified Files: setup.py Log Message: Updated towards 0.9b fixing a few minor code issues and the docs. Not yet able to build with gmp 4 (probably misinstalled gmp?). Index: setup.py =================================================================== RCS file: /cvsroot/gmpy/gmpy/setup.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** setup.py 24 Jan 2002 14:17:06 -0000 1.1.1.1 --- setup.py 1 Mar 2002 08:19:44 -0000 1.2 *************** *** 4,7 **** --- 4,8 ---- if sys.version.find('MSC')==-1: gmpy_ext = Extension('gmpy', sources=['src/gmpy.c'], + # library_dirs=['/usr/local/lib'], libraries=['gmp']) else: |
From: Gustavo N. <nie...@us...> - 2002-01-24 14:20:21
|
Update of /cvsroot/gmpy/gmpy In directory usw-pr-cvs1:/tmp/cvs-serv3050 Log Message: Imported gmpy into CVS. Status: Vendor Tag: import_vendor Release Tags: import_release N gmpy/setes.py N gmpy/setup.py N gmpy/doc/gmpydoc.txt N gmpy/doc/index.html N gmpy/src/gmpy.c N gmpy/src/gmpy.h N gmpy/src/pysymbolicext.c N gmpy/test/doctest.py N gmpy/test/gmpy_test_08_cvr.py N gmpy/test/gmpy_test_08_mpf.py N gmpy/test/gmpy_test_08_mpq.py N gmpy/test/gmpy_test_08_mpz.py N gmpy/test/gmpy_test_08.py N gmpy/test/gmpy_test_08_rnd.py N gmpy/test/timing1.py N gmpy/test/timing2.py N gmpy/test/timing3.py No conflicts created by this import ***** Bogus filespec: - Imported sources |
From: Gustavo N. <nie...@us...> - 2001-12-11 10:30:04
|
Update of /cvsroot/gmpy/gmpy/src In directory usw-pr-cvs1:/tmp/cvs-serv30377/src Added Files: gmpy.c gmpy.h pysymbolicext.c Log Message: Added files to repository. --- NEW FILE: gmpy.c --- /* gmpy.c * * Python interface to the GMP multiple precision library, * originally written for GMP-2.0 (by AMK...?) * Rewritten by Niels Möller, May 1996 * * Version for GMP-3, Python-2, with support for MSVC++6. * addition of mpf's, &c: Alex Martelli (al...@ya..., Nov 2000). * * 0.1, pre-alpha; date: 2000-11-06 first placed on sourceforge * * 0.2, still pre-alpha: 2000-11-15: bugfixes re formatting (tx, Peanu!) * no tags on oct() and hex() of mpz's * insert 'tagoff' in options (gmpy.mpz() vs mpz() in repr) (for Peanu!) * speedups for _nonzero & _cmp (tx, Peanu!) * slight speedup (7/8%?) for excess reallocs 4<->8 bytes (Peanu's help!) * added copy/fcopy; bin; fib; remove * * 0.3, still pre-alpha, but...: [...5514 lines suppressed...] which are not built-in features of Python.\n\ "; void initgmpy(void) { Pympz_Type.ob_type = &PyType_Type; Pympq_Type.ob_type = &PyType_Type; Pympf_Type.ob_type = &PyType_Type; if (options.debug) fputs( "initgmpy() called...\n", stderr ); _PyInitGMP(); gmpy_module = Py_InitModule3("gmpy", Pygmpy_methods, _gmpy_docs); export_gmpy(gmpy_module); if (options.debug) fprintf(stderr, "gmpy_module at %p\n", gmpy_module); } --- NEW FILE: gmpy.h --- /* gmpy C API extension header file. Part of Python's gmpy module since version 0.4 Created by Pearu Peterson <pe...@ce...>, November 2000. Edited by A. Martelli <al...@ya...>, December 2000. Version 0.8. */ #ifndef Py_GMPYMODULE_H #define Py_GMPYMODULE_H #ifdef __cplusplus extern "C" { #endif #if defined(MS_WIN32) && defined(_MSC_VER) /* the __MPN determination in stock gmp.h doesn't work, so...: */ # define __MPN(x) __gmpn_##x # define _GMP_H_HAVE_FILE # define _PROTO(x) x #endif #include "gmp.h" /* Header file for gmpy */ typedef struct { PyObject_HEAD /* PyObject* callable; */ /* long flags; */ } mpob; typedef struct { mpob ob; mpz_t z; } PympzObject; typedef struct { mpob ob; mpq_t q; } PympqObject; typedef struct { mpob ob; mpf_t f; unsigned int rebits; } PympfObject; /* #define MPOBCAL(obj) ((mpob*)obj)->callable */ /* #define MPOBFLA(obj) ((mpob*)obj)->flags */ #define Pympz_AS_MPZ(obj) (((PympzObject *)(obj))->z) #define Pympq_AS_MPQ(obj) (((PympqObject *)(obj))->q) #define Pympf_AS_MPF(obj) (((PympfObject *)(obj))->f) #define Pympz_Type_NUM 0 #define Pympq_Type_NUM 1 #define Pympf_Type_NUM 2 /* C API functions */ #define Pympz_new_NUM 3 #define Pympz_new_RETURN PympzObject * #define Pympz_new_PROTO (void) #define Pympq_new_NUM 4 #define Pympq_new_RETURN PympqObject * #define Pympq_new_PROTO (void) #define Pympf_new_NUM 5 #define Pympf_new_RETURN PympfObject * #define Pympf_new_PROTO (unsigned int bits) #define Pympz_dealloc_NUM 6 #define Pympz_dealloc_RETURN void #define Pympz_dealloc_PROTO (PympzObject *self) #define Pympq_dealloc_NUM 7 #define Pympq_dealloc_RETURN void #define Pympq_dealloc_PROTO (PympqObject *self) #define Pympf_dealloc_NUM 8 #define Pympf_dealloc_RETURN void #define Pympf_dealloc_PROTO (PympfObject *self) #define Pympz_convert_arg_NUM 9 #define Pympz_convert_arg_RETURN int #define Pympz_convert_arg_PROTO (PyObject *arg, PyObject **ptr) #define Pympq_convert_arg_NUM 10 #define Pympq_convert_arg_RETURN int #define Pympq_convert_arg_PROTO (PyObject *arg, PyObject **ptr) #define Pympf_convert_arg_NUM 11 #define Pympf_convert_arg_RETURN int #define Pympf_convert_arg_PROTO (PyObject *arg, PyObject **ptr) /* Total number of C API pointers */ #define Pygmpy_API_pointers 12 #ifdef GMPY_MODULE /* This section is used when compiling gmpy.c */ extern PyTypeObject Pympz_Type; #define Pympz_Check(v) (((PyObject*)v)->ob_type == &Pympz_Type) extern PyTypeObject Pympq_Type; #define Pympq_Check(v) (((PyObject*)v)->ob_type == &Pympq_Type) extern PyTypeObject Pympf_Type; #define Pympf_Check(v) (((PyObject*)v)->ob_type == &Pympf_Type) static Pympz_new_RETURN Pympz_new Pympz_new_PROTO; static Pympz_dealloc_RETURN Pympz_dealloc Pympz_dealloc_PROTO; static Pympz_convert_arg_RETURN Pympz_convert_arg Pympz_convert_arg_PROTO; static Pympq_new_RETURN Pympq_new Pympq_new_PROTO; static Pympq_dealloc_RETURN Pympq_dealloc Pympq_dealloc_PROTO; static Pympq_convert_arg_RETURN Pympq_convert_arg Pympq_convert_arg_PROTO; static Pympf_new_RETURN Pympf_new Pympf_new_PROTO; static Pympf_dealloc_RETURN Pympf_dealloc Pympf_dealloc_PROTO; static Pympf_convert_arg_RETURN Pympf_convert_arg Pympf_convert_arg_PROTO; #define export_gmpy(m) { \ PyObject *d; \ static void *Pygmpy_API[Pygmpy_API_pointers]; \ PyObject *c_api_object; \ \ Pygmpy_API[Pympz_Type_NUM] = (void*)&Pympz_Type;\ Pygmpy_API[Pympq_Type_NUM] = (void*)&Pympq_Type;\ Pygmpy_API[Pympf_Type_NUM] = (void*)&Pympf_Type;\ \ Pygmpy_API[Pympz_new_NUM] = (void*)Pympz_new;\ Pygmpy_API[Pympz_dealloc_NUM] = (void*)Pympz_dealloc;\ Pygmpy_API[Pympz_convert_arg_NUM] = (void*)Pympz_convert_arg;\ Pygmpy_API[Pympq_new_NUM] = (void*)Pympq_new;\ Pygmpy_API[Pympq_dealloc_NUM] = (void*)Pympq_dealloc;\ Pygmpy_API[Pympq_convert_arg_NUM] = (void*)Pympq_convert_arg;\ Pygmpy_API[Pympf_new_NUM] = (void*)Pympf_new;\ Pygmpy_API[Pympf_dealloc_NUM] = (void*)Pympf_dealloc;\ Pygmpy_API[Pympf_convert_arg_NUM] = (void*)Pympf_convert_arg;\ \ c_api_object = PyCObject_FromVoidPtr((void*)Pygmpy_API, NULL);\ d = PyModule_GetDict(m);\ PyDict_SetItemString(d, "_C_API", c_api_object);\ } #else /* This section is used in modules that use gmpy's API */ static void **Pygmpy_API; #define Pypmz_Check(op) \ ((op)->ob_type == (PyTypeObject *)Pygmpy_API[Pympz_Type_NUM]) #define Pympz_Type (*(PyTypeObject *)Pygmpy_API[Pympz_Type_NUM]) #define Pypmq_Check(op) \ ((op)->ob_type == (PyTypeObject *)Pygmpy_API[Pympq_Type_NUM]) #define Pympq_Type (*(PyTypeObject *)Pygmpy_API[Pympq_Type_NUM]) #define Pypmf_Check(op) \ ((op)->ob_type == (PyTypeObject *)Pygmpy_API[Pympf_Type_NUM]) #define Pympf_Type (*(PyTypeObject *)Pygmpy_API[Pympf_Type_NUM]) #define Pympz_new \ (*(Pympz_new_RETURN (*)Pympz_new_PROTO) Pygmpy_API[Pympz_new_NUM]) #define Pympz_dealloc \ (*(Pympz_dealloc_RETURN (*)Pympz_dealloc_PROTO) Pygmpy_API[Pympz_dealloc_NUM]) #define Pympz_convert_arg \ (*(Pympz_convert_arg_RETURN (*)Pympz_convert_arg_PROTO) Pygmpy_API[Pympz_convert_arg_NUM]) #define Pympq_new \ (*(Pympq_new_RETURN (*)Pympq_new_PROTO) Pygmpy_API[Pympq_new_NUM]) #define Pympq_dealloc \ (*(Pympq_dealloc_RETURN (*)Pympq_dealloc_PROTO) Pygmpy_API[Pympq_dealloc_NUM]) #define Pympq_convert_arg \ (*(Pympq_convert_arg_RETURN (*)Pympq_convert_arg_PROTO) Pygmpy_API[Pympq_convert_arg_NUM]) #define Pympf_new \ (*(Pympf_new_RETURN (*)Pympf_new_PROTO) Pygmpy_API[Pympf_new_NUM]) #define Pympf_dealloc \ (*(Pympf_dealloc_RETURN (*)Pympf_dealloc_PROTO) Pygmpy_API[Pympf_dealloc_NUM]) #define Pympf_convert_arg \ (*(Pympf_convert_arg_RETURN (*)Pympf_convert_arg_PROTO) Pygmpy_API[Pympf_convert_arg_NUM]) #define import_gmpy() \ { \ PyObject *module = PyImport_ImportModule("gmpy");\ if (module != NULL) { \ PyObject *module_dict = PyModule_GetDict(module); \ PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \ if (PyCObject_Check(c_api_object)) { \ Pygmpy_API = (void **)PyCObject_AsVoidPtr(c_api_object); \ } \ } \ } #endif #ifdef __cplusplus } #endif #endif /* !defined(Py_GMPYMODULE_H */ --- NEW FILE: pysymbolicext.c --- /* PySymbolic GMP extensions (in connection with gmpy). 1) Factoring with Pollard's rho method. Copied relevant functions from demos/factorice.c of the GMP distribution, and modified them to be used in Python. Copyright 2000 Pearu Peterson all rights reserved, Pearu Peterson <pe...@io...> Permission to use, modify, and distribute this software is given under the terms of the LGPL. See http://www.fsf.org NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. $Revision: 1.1 $ $Date: 2001/12/11 10:30:00 $ Pearu Peterson */ #include <assert.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include "Python.h" #include "gmpy.h" static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6}; #if defined (__hpux) || defined (__alpha) || defined (__svr4__) || defined (__SVR4) /* HPUX lacks random(). DEC OSF/1 1.2 random() returns a double. */ long mrand48 (); static long random () { return mrand48 (); } #else /* Glibc stdlib.h has "int32_t random();" which, on i386 at least, conflicts with a redeclaration as "long". */ #if defined(_MSC_VER) long random() { return rand(); } #endif #ifndef __GLIBC__ long random (); #endif #endif static void res_append_si(PyObject *res,signed long int f,unsigned long int c) { if (c) { PyObject *pair = (PyObject *)PyTuple_New(2); { PyObject *z = (PyObject *)Pympz_new(); mpz_set_si(Pympz_AS_MPZ(z),f); PyTuple_SetItem(pair,0,z); } { PyObject *z = (PyObject *)Pympz_new(); mpz_set_ui(Pympz_AS_MPZ(z),c); PyTuple_SetItem(pair,1,z); } PyList_Append(res,pair); Py_DECREF(pair); } } static void res_append(PyObject *res,unsigned long int f,unsigned long int c) { if (c) { PyObject *pair = (PyObject *)PyTuple_New(2); { PyObject *z = (PyObject *)Pympz_new(); mpz_set_ui(Pympz_AS_MPZ(z),f); PyTuple_SetItem(pair,0,z); } { PyObject *z = (PyObject *)Pympz_new(); mpz_set_ui(Pympz_AS_MPZ(z),c); PyTuple_SetItem(pair,1,z); } PyList_Append(res,pair); Py_DECREF(pair); } } static void res_append_mpz(PyObject *res,mpz_t f,unsigned long int c) { if (c) { PyObject *pair = (PyObject *)PyTuple_New(2); { PyObject *z = (PyObject *)Pympz_new(); mpz_set(Pympz_AS_MPZ(z),f); PyTuple_SetItem(pair,0,z); } { PyObject *z = (PyObject *)Pympz_new(); mpz_set_ui(Pympz_AS_MPZ(z),c); PyTuple_SetItem(pair,1,z); } PyList_Append(res,pair); Py_DECREF(pair); } } static void factor_using_division (mpz_t t, unsigned int limit, PyObject *res) { mpz_t q, r; unsigned long int f; int ai; unsigned *addv = add; unsigned int failures; unsigned long int count; mpz_init (q); mpz_init (r); count = 0; f = mpz_scan1 (t, 0); mpz_div_2exp (t, t, f); res_append(res,2,f); count = 0; for (;;) { mpz_tdiv_qr_ui (q, r, t, 3); if (mpz_cmp_ui (r, 0) != 0) break; mpz_set (t, q); count++; } res_append(res,3,count); count = 0; for (;;) { mpz_tdiv_qr_ui (q, r, t, 5); if (mpz_cmp_ui (r, 0) != 0) break; mpz_set (t, q); count++; } res_append(res,5,count); failures = 0; f = 7; ai = 0; count = 0; while (mpz_cmp_ui (t, 1) != 0) { mpz_tdiv_qr_ui (q, r, t, f); if (mpz_cmp_ui (r, 0) != 0) { res_append(res,f,count); count = 0; f += addv[ai]; if (mpz_cmp_ui (q, f) < 0) break; ai = (ai + 1) & 7; failures++; if (failures > limit) break; } else { mpz_swap (t, q); failures = 0; count++; } } res_append(res,f,count); mpz_clear (q); mpz_clear (r); } static void factor_using_division_2kp (mpz_t t, unsigned int limit, unsigned long p, PyObject *res) { mpz_t r; mpz_t f; unsigned int k; unsigned long int count; mpz_init (r); mpz_init_set_ui (f, 2 * p); mpz_add_ui (f, f, 1); for (k = 1; k < limit; k++) { mpz_tdiv_r (r, t, f); count = 0; while (mpz_cmp_ui (r, 0) == 0) { mpz_tdiv_q (t, t, f); mpz_tdiv_r (r, t, f); count++; } res_append_mpz(res,f,count); mpz_add_ui (f, f, 2 * p); } mpz_clear (f); mpz_clear (r); } static void factor_using_pollard_rho (mpz_t n, int a_int, unsigned long p,PyObject *res) { mpz_t x, x1, y, P; mpz_t a; mpz_t g; mpz_t t1, t2; int k, l, c, i; unsigned long int count; mpz_init (g); mpz_init (t1); mpz_init (t2); mpz_init_set_si (a, a_int); mpz_init_set_si (y, 2); mpz_init_set_si (x, 2); mpz_init_set_si (x1, 2); k = 1; l = 1; mpz_init_set_ui (P, 1); c = 0; count = 0; while (mpz_cmp_ui (n, 1) != 0) { S2: if (p != 0) { mpz_powm_ui (x, x, p, n); mpz_add (x, x, a); } else { mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n); } mpz_sub (t1, x1, x); mpz_mul (t2, P, t1); mpz_mod (P, t2, n); c++; if (c == 20) { c = 0; mpz_gcd (g, P, n); if (mpz_cmp_ui (g, 1) != 0) goto S4; mpz_set (y, x); } /* S3: */ k--; if (k != 0) goto S2; mpz_gcd (g, P, n); if (mpz_cmp_ui (g, 1) != 0) goto S4; mpz_set (x1, x); k = l; l = 2 * l; for (i = 0; i < k; i++) { if (p != 0) { mpz_powm_ui (x, x, p, n); mpz_add (x, x, a); } else { mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n); } } mpz_set (y, x); c = 0; goto S2; S4: do { if (p != 0) { mpz_powm_ui (y, y, p, n); mpz_add (y, y, a); } else { mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n); } mpz_sub (t1, x1, y); mpz_gcd (g, t1, n); } while (mpz_cmp_ui (g, 1) == 0); if (!mpz_probab_prime_p (g, 3)) { do a_int = random (); while (a_int == -2 || a_int == 0); factor_using_pollard_rho (g, a_int, p, res); break; } else count ++; res_append_mpz(res,g,count); count = 0; mpz_div (n, n, g); mpz_mod (x, x, n); mpz_mod (x1, x1, n); mpz_mod (y, y, n); if (mpz_probab_prime_p (n, 3)) { count++; break; } } res_append_mpz(res,n,count); mpz_clear (g); mpz_clear (P); mpz_clear (t2); mpz_clear (t1); mpz_clear (a); mpz_clear (x1); mpz_clear (x); mpz_clear (y); } static void factor (mpz_t t, unsigned long p,PyObject *res) { unsigned int division_limit; /* Set the trial division limit according the size of t. */ division_limit = mpz_sizeinbase (t, 2); if (division_limit > 1000) division_limit = 1000 * 1000; else division_limit = division_limit * division_limit; if (p != 0) factor_using_division_2kp (t, division_limit / 10, p, res); else factor_using_division (t, division_limit, res); if (mpz_cmp_ui (t, 1) != 0) if (mpz_probab_prime_p (t, 3)) res_append_mpz(res,t,1); else factor_using_pollard_rho (t, 1, p, res); } static char doc_factor[] = "factor(t,m=0) -> prime factors of t (modulo m)\n\ \n\ Prime decomposition of t (modulo m).\n\ factor(t,m) returns a list of tuples (f,p) where p is the number\n\ of prime factors f in term t. p is always positive.\n\ t can be also zero or negative.\n\ For m=0 the following condition holds\n\ t == reduce(lambda r,pm:r*pm[0]**pm[1],factor(t),1L)."; static PyObject * Pysym_factor(PyObject *self, PyObject *args) { mpz_t t; unsigned long p; PyObject *t_py = NULL; PyObject *p_py = NULL; PyObject *res = NULL; if (!PyArg_ParseTuple(args, "O&|O&",\ Pympz_convert_arg,&t_py,\ Pympz_convert_arg,&p_py)) return NULL; res = PyList_New(0); if (p_py==NULL) p = 0; else p = mpz_get_ui(Pympz_AS_MPZ(p_py)); mpz_init_set(t,Pympz_AS_MPZ(t_py)); if (mpz_sgn(t)==0) { res_append(res,0,1); return res; } if (mpz_sgn(t)==-1) { res_append_si(res,-1,1); mpz_neg(t,t); } factor(t,p,res); if (PyList_Size(res)==0) res_append(res,1,1); return res; } statichere PyMethodDef Pysym_methods [] = { { "factor", Pysym_factor, METH_VARARGS, doc_factor }, { NULL, NULL} }; void initpysymbolicext(void) { Py_InitModule("pysymbolicext", Pysym_methods); import_gmpy(); } |
From: Gustavo N. <nie...@us...> - 2001-12-11 10:30:04
|
Update of /cvsroot/gmpy/gmpy/test In directory usw-pr-cvs1:/tmp/cvs-serv30377/test Added Files: doctest.py gmpy_test_08.py gmpy_test_08_cvr.py gmpy_test_08_mpf.py gmpy_test_08_mpq.py gmpy_test_08_mpz.py gmpy_test_08_rnd.py timing1.py timing2.py timing3.py Log Message: Added files to repository. --- NEW FILE: doctest.py --- # Module doctest version 0.9.4 # Released to the public domain 27-Mar-1999, # by Tim Peters (ti...@em...). # Provided as-is; use at your own risk; no warranty; no promises; enjoy! """Module doctest -- a framework for running examples in docstrings. NORMAL USAGE In normal use, end each module M with: def _test(): import doctest, M # replace M with your module's name return doctest.testmod(M) # ditto if __name__ == "__main__": _test() [...1074 lines suppressed...] -42 """ return self.val __test__ = {"_TestClass": _TestClass, "string": r""" Example of a string object, searched as-is. >>> x = 1; y = 2 >>> x + y, x * y (3, 2) """ } def _test(): import doctest return doctest.testmod(doctest) if __name__ == "__main__": _test() --- NEW FILE: gmpy_test_08.py --- r''' >>> gmpy.version() '0.8.0d' >>> ''' import sys import doctest import gmpy if sys.argv[-1] == 'debug': gmpy.set_debug(1) import gmpy_test_08_cvr import gmpy_test_08_rnd import gmpy_test_08_mpf import gmpy_test_08_mpq import gmpy_test_08_mpz test_modules = (gmpy_test_08_cvr, gmpy_test_08_rnd, gmpy_test_08_mpf, gmpy_test_08_mpq, gmpy_test_08_mpz ) _g = gmpy print "Unit tests for gmpy 0.8 pre-alpha" print " on Python",sys.version print "Testing gmpy %s (GMP %s), default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) pf, pt = 0, 0 for x in test_modules: print x.__name__, failures, tests = x._test() print "%3d tests, %d failures" % (tests-pt, failures-pf) pf, pt = failures, tests doctest.master.summarize(1) --- NEW FILE: gmpy_test_08_cvr.py --- # partial unit test for gmpy 0.9 extra cover # relies on Tim Peters' "doctest.py" test-driver # test-version 0.9 r''' >>> _g.gmp_version() '3.1.1' >>> _g.version() '0.9.0b' ''' import gmpy as _g, doctest, sys __test__={} r = _g.rand __test__['misc_stuff']=\ r''' >>> junk=_g.set_debug(0) >>> knuj=_g.set_debug(junk) >>> junk==_g.set_debug(junk) 1 >>> _g.set_fcoform(None) >>> _g.set_fcoform() >>> print _g.mpf(3.0) 3.0 >>> ''' __test__['user_errors']=\ r''' >>> _g.version(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.gmp_version(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.get_zcache(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_zcache(2000) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_zcache(-23) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.get_qcache(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_qcache(2000) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_qcache(-42) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.get_zconst(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 0 arguments (1 given) >>> _g.set_zconst() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (0 given) >>> _g.set_zconst(23) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (1 given) >>> _g.set_zconst(23,45,67) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 2 arguments (3 given) >>> _g.set_zconst(23,'blub') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.set_zconst(-1000,1000) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_zconst(100,-100) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: cache must between 0 and 1000 >>> _g.set_debug() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 1 argument (0 given) >>> _g.set_debug(2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes exactly 1 argument (2 given) >>> _g.set_debug('boh') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.set_minprec(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: minimum precision must be >= 0 >>> _g.set_fcoform(33) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: number of digits n must be 0<n<=30 >>> _g.set_fcoform([]) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: set_fcoform argument must be int, string, or None >>> _g.mpz('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpf('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpq('12'+chr(0)+'34') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string without NULL characters expected >>> _g.mpq('bo',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (too short) >>> _g.mpq('bologna',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (num len) >>> _g.mpq('\001\000\000\000\003\002',256) mpq(3,2) >>> _g.mpq('\002\000\000\000\003\377\002',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (num sgn) >>> _g.mpq('\001\000\000\000\003\002\377',256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid mpq binary (den sgn) >>> _g.mpq('ba/bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> print 'ba/bo' ba/bo >>> _g.mpq('1/bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> print '1/bo' 1/bo >>> _g.mpq('1/0') Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq: zero denominator >>> _g.mpf([]) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() expects numeric or string argument >>> _g.mpf('bo',0,256) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: string too short to be a gmpy.mpf binary encoding >>> _g.mpf('bo') Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid digits >>> int(_g.mpz(1000*1000*1000*1000L)) Traceback (most recent call last): File "<stdin>", line 1, in ? OverflowError: mpz too large for int >>> _g.scan0(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: starting bit must be >= 0 >>> _g.scan1(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: starting bit must be >= 0 >>> _g.lowbits(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: nbits must be > 0 >>> _g.getbit(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bit_index must be >= 0 >>> _g.setbit(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bit_index must be >= 0 >>> _g.mpz(23).setbit(12,1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 2 arguments (4 given) >>> _g.setbit(12,1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 3 arguments (4 given) >>> _g.root(12,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be > 0 >>> _g.root(12,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be > 0 >>> _g.root(-12,2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: root of negative number >>> _g.digits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.fdigits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.qdigits(3.14,'peep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.mpz(3).digits('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.mpf(3).digits('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: an integer is required >>> _g.qdiv(3,_g.mpq(1)) mpz(3) >>> _g.qdiv(3,_g.mpz(1)) mpz(3) >>> _g.qdiv(3,_g.mpf(1)) mpz(3) >>> _g.qdiv(3,1.0) mpz(3) >>> _g.qdiv(3,1L) mpz(3) >>> _g.qdiv(3) mpz(3) >>> _g.qdiv(3,'bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: second argument to qdiv not a number >>> _g.mpq(2).qdiv(3,4) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 1 argument (2 given) >>> _g.qdiv(3,4,5) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function takes at most 2 arguments (3 given) >>> _g.qdiv('bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: first argument to qdiv not a number >>> _g.qdiv(1.0,1) mpz(1) >>> _g.qdiv(1.0,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: qdiv: zero divisor >>> _g.f2q(-1.0) mpz(-1) >>> _g.mpz(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() requires 1 or 2 arguments >>> _g.mpz('bi','bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz(): base must be an integer >>> _g.mpz('bi',99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpz must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpz(1,2) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() with numeric argument needs exactly 1 argument >>> _g.mpz(None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpz() expects numeric or string argument >>> _g.mpq(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq() requires 1 or 2 arguments >>> _g.mpq('bi','bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq(): base must be an integer >>> _g.mpq('bi',99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpq() must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpq(None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpq() expects numeric or string argument >>> _g.mpq(1,None) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpq >>> _g.mpq(1,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq: zero denominator >>> _g.mpf() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() requires 1 to 3 arguments >>> _g.mpf(1,'bo') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf(): bits must be an integer >>> _g.mpf(1,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: bits for gmpy.mpf must be >= 0 >>> _g.mpf('ba',0,'bu') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf(): base must be an integer >>> _g.mpf('ba',0,99) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: base for gmpy.mpf must be 0, 256, or in the interval 2 ... 36 . >>> _g.mpf(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: gmpy.mpf() with numeric 1st argument needs 1 or 2 arguments >>> +_g.mpz(1) mpz(1) >>> +_g.mpf(1) mpf('1.e0') >>> +_g.mpq(1) mpq(1) >>> _g.mpz(2)**-2 Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow with negative power >>> _g.mpz(2)**_g.mpz(1000000*1000000L) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow outrageous exponent >>> pow(_g.mpz(2),3,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpz.pow divide by zero >>> pow(_g.mpz(2),3,-5) mpz(-2) >>> pow(_g.mpq(2),3,-5) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow no modulo allowed >>> a=1000000L**2 >>> _g.mpq(2)**a Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow outrageous exp num >>> _g.mpq(2)**_g.mpq(1,a) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow outrageous exp den >>> _g.mpq(2)**0 mpq(1) >>> _g.mpq(2)**-1 mpq(1,2) >>> _g.mpq(2)**_g.mpq(1,2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpq.pow fractional exponent, inexact-root >>> _g.mpq(0)**_g.mpq(1,2) mpq(0) >>> _g.mpq(0)**-1 Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpq.pow 0 base to <0 exponent >>> _g.mpq(-1)**-1 mpq(-1) >>> _g.mpf(9,100)**2 mpf('8.1e1',100) >>> _g.mpf(9,100)**0.5 mpf('3.e0',100) >>> _g.mpf(9,100)**_g.mpf(0.5) mpf('3.e0') >>> pow(_g.mpf(2),3,-5) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: mpf.pow no modulo allowed >>> _g.mpz(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpz type failed >>> _g.mpz(1)+_g.mpf(1) mpf('2.e0') >>> _g.mpz(1)+_g.mpq(1) mpq(2) >>> _g.mpq(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpq type failed >>> _g.mpf(1)+'bu' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: coercion to gmpy.mpf type failed >>> _g.mpf(1)+_g.mpq(2) mpq(3) >>> divmod(_g.mpz(3),0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: mpz.divmod by zero >>> divmod(_g.mpz(0),3) (mpz(0), mpz(0)) >>> _g.divm(1,2,0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: not invertible >>> abs(_g.mpq(0)) mpq(0) >>> _g.mpz(0)**2 mpz(0) >>> _g.mpq(-2)**0 mpq(1) >>> _g.fac(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: factorial of negative number >>> _g.fib(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Fibonacci of negative number >>> _g.comb(7,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: binomial coefficient with negative k >>> _g.sqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.sqrtrem(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.fsqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.9 pre-alpha (extra cover)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching" \ "(%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with empty callbacks" def _zd(where,*args): if where=='qdiv': raise ZeroDivisionError, "qdiv: zero divisor" elif where=='mpz_divmod': raise ZeroDivisionError, "mpz.divmod by zero" elif where=='mpq_pow': raise ZeroDivisionError, "mpq.pow 0 base to <0 exponent" elif where=='divm': raise ZeroDivisionError, "not invertible" else: raise ZeroDivisionError, "mpq: zero denominator" def _zm(*args): return None def _at(self,name): return name.upper() def _er(where, what, *args): raise ValueError, what _g.set_callback('ZM',_zm) _g.set_callback('ZD',_zd) _g.set_callback('ER',_er) _g.set_callback('AT',_at) class _Fakenum: def __gmpy__(self, where, args, other, extype, exvalue): raise extype, exvalue _fn = _Fakenum() try: x = _g.getbit(_fn,17) except TypeError: pass try: x = _g.divm(23,45,_fn) except TypeError: pass assert(_g.mpz(23).foop=='FOOP') assert(_g.mpq(23).foop=='FOOP') assert(_g.mpf(23).foop=='FOOP') # avoid merge-reports for the second run sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav # just generate a little extra coverage...! _g.set_callback('ZM') _g.set_callback('ZD',None) _g.set_callback('ER') _g.set_callback('AT') try: _g.set_callback('ZD',23,45) except: pass try: _g.set_callback('ZD',23) except: pass try: _g.set_callback('ZZ') except: pass if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_08_mpf.py --- # partial unit test for gmpy 0.8 mpf functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 0.8 r''' >>> dir(a) ['_copy', 'binary', 'ceil', 'digits', 'f2q', 'floor', 'getprec', 'getrprec', 'qdiv', 'reldiff', 'setprec', 'sign', 'sqrt', 'trunc'] >>> ''' import gmpy as _g, doctest, sys __test__={} a=_g.mpf('123.456') b=_g.mpf('789.123') __test__['elemop']=\ r''' >>> print a+b 912.579 >>> print a-b -665.667 >>> print a*b 97421.969088 >>> print a/b 0.156447093799065544915 >>> print b+a 912.579 >>> print b-a 665.667 >>> print b*a 97421.969088 >>> print b/a 6.39193720839813374806 >>> print -a -123.456 >>> print abs(-a) 123.456 >>> _g.fsign(b-a) 1 >>> _g.fsign(b-b) 0 >>> _g.fsign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> import math >>> math.ceil(a) 124.0 >>> print a.ceil() 124.0 >>> print _g.ceil(a) 124.0 >>> math.floor(a) 123.0 >>> print a.floor() 123.0 >>> print _g.floor(a) 123.0 >>> print a.trunc() 123.0 >>> print _g.trunc(a) 123.0 >>> x=-a >>> math.floor(x) -124.0 >>> print x.floor() -124. >>> print _g.floor(x) -124. >>> print x.ceil() -123. >>> math.ceil(x) -123.0 >>> print _g.ceil(x) -123. >>> print x.trunc() -123. >>> print _g.trunc(x) -123. >>> _g.ceil(12.3)==math.ceil(12.3) 1 >>> _g.floor(12.3)==math.floor(12.3) 1 >>> _g.ceil(-12.3)==math.ceil(-12.3) 1 >>> _g.floor(-12.3)==math.floor(-12.3) 1 >>> (a**2).reldiff(float(a)**2) < (2.0**-(a.getrprec()-1)) 1 >>> (a**2).reldiff(a*a) < (2.0**-(a.getprec()-1)) 1 >>> (b**2).reldiff(float(b)**2) < (2.0**-(b.getrprec()-1)) 1 >>> (b**2).reldiff(b*b) < (2.0**-(b.getprec()-1)) 1 >>> a.sqrt() mpf('1.11110755554986664846e1') >>> _g.fsqrt(a) mpf('1.11110755554986664846e1') >>> _g.fsqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? File "a.py", line 9, in _er raise ValueError, what ValueError: sqrt of negative number >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpf(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpf(0) 1 >>> not a 0 >>> coerce(a,1) (mpf('1.23456e2'), mpf('1.e0')) >>> coerce(1,a) (mpf('1.e0'), mpf('1.23456e2')) >>> coerce(a,1.0) (mpf('1.23456e2'), mpf('1.e0')) >>> a.f2q(0.1) mpz(123) >>> a.f2q(0.01) mpz(123) >>> a.f2q(0.001) mpq(247,2) >>> a.f2q(0.0001) mpq(1358,11) >>> a.f2q(0.00001) mpq(7037,57) >>> a.f2q(0.000001) mpq(15432,125) >>> a.f2q(0.0000001) mpq(15432,125) >>> a.f2q() mpq(15432,125) >>> print _g.mpf(_g.mpz(1234)) 1234.0 >>> x=1000*1000*1000*1000L >>> _g.mpf(x) mpf('1.e12') >>> c=_g.mpf(a) >>> a is c 1 >>> c=_g.mpf(a,99) >>> a is c 0 >>> a==c 1 >>> ''' __test__['format']=\ r''' >>> str(a) '123.456' >>> repr(a) "mpf('1.23456e2')" >>> _g.set_tagoff(0) 1 >>> a gmpy.mpf('1.23456e2') >>> _g.set_tagoff(1) 0 >>> a.digits(10,0) '1.23456e2' >>> a.digits(10,1) '1.e2' >>> a.digits(10,2) '1.2e2' >>> a.digits(10,3) '1.23e2' >>> a.digits(10,4) '1.235e2' >>> a.digits(10,5) '1.2346e2' >>> a.digits(10,6) '1.23456e2' >>> a.digits(10,7) '1.23456e2' >>> a.digits(10,8) '1.23456e2' >>> junk=_g.set_fcoform(14) >>> frmt=_g.set_fcoform(14) >>> frmt '%.14e' >>> ofmt=_g.set_fcoform(frmt) >>> ofmt '%.14e' >>> _g.mpf(3.4) mpf('3.4e0') >>> print _g.mpf(3.4) 3.4 >>> for i in range(11,99): ... assert str(_g.mpf(i/10.0))==str(i/10.0) ... >>> a.digits(1) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: base must be either 0 or in the interval 2 ... 36 >>> a.digits(2,-1) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: digits must be >= 0 >>> a.digits(10,0,0,-1,2) ('123456', 3, 53) >>> saveprec=a.getrprec() >>> a.setprec(33) >>> a mpf('1.23456e2',33) >>> a.setprec(saveprec) >>> a.getrprec()==saveprec 1 >>> _g.fdigits(2.2e5, 0, 6, -10, 10) '220000.0' >>> _g.fdigits(2.2e-5, 0, 6, -10, 10) '0.000022' >>> _g.digits(_g.mpf(23.45)) '23' >>> _g.fbinary('pep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpf >>> ''' __test__['binio']=\ r''' >>> epsilon=_g.mpf(2)**-(a.getrprec()) >>> ba=a.binary() >>> a.reldiff(_g.mpf(ba,0,256)) <= epsilon 1 >>> len(ba) 18 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 8 53 0 0 0 1 0 0 0 123 116 188 106 126 249 219 34 209 >>> na=(-a).binary() >>> (-a).reldiff(_g.mpf(na,0,256)) <= epsilon 1 >>> na[0] == chr(ord(ba[0])|1) 1 >>> for bd,nd in zip(ba[1:],na[1:]): ... assert bd==nd >>> ia=(1/a).binary() >>> (1/a).reldiff(_g.mpf(ia,0,256)) <= epsilon 1 >>> _g.fbinary(0) '\x085\x00\x00\x00\x00\x00\x00\x00' >>> _g.fbinary(0.5) '\x085\x00\x00\x00\x00\x00\x00\x00\x80' >>> _g.fbinary(-0.5) '\t5\x00\x00\x00\x00\x00\x00\x00\x80' >>> _g.fbinary(-2.0) '\t5\x00\x00\x00\x01\x00\x00\x00\x02' >>> _g.fbinary(2.0) '\x085\x00\x00\x00\x01\x00\x00\x00\x02' >>> prec=_g.set_minprec(0) >>> junk=_g.set_minprec(prec) >>> a.getrprec()==prec 1 >>> b.getrprec()==prec 1 >>> _g.mpf(1.0).getrprec()==prec 1 >>> hash(_g.mpf(23.0))==hash(23) 1 >>> print _g.mpf('\004',0,256) 0.0 >>> long(a) 123L >>> long(-a) -123L >>> int(a) 123 >>> int(-a) -123 >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.8 pre-alpha (mpf functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print print "Overall results for mpf:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_08_mpq.py --- # partial unit test for gmpy 0.8 mpq functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 0.8 r''' >>> dir(a) ['_copy', 'binary', 'denom', 'digits', 'numer', 'qdiv', 'sign'] >>> ''' import gmpy as _g, doctest,sys __test__={} a=_g.mpq('123/456') b=_g.mpq('789/123') __test__['elemop']=\ r''' >>> a+b mpq(41657,6232) >>> a-b mpq(-38295,6232) >>> a*b mpq(263,152) >>> a/b mpq(1681,39976) >>> b+a mpq(41657,6232) >>> b-a mpq(38295,6232) >>> b*a mpq(263,152) >>> b/a mpq(39976,1681) >>> a+1 mpq(193,152) >>> 1+a mpq(193,152) >>> a-1 mpq(-111,152) >>> 1-a mpq(111,152) >>> a*1 mpq(41,152) >>> 1*a mpq(41,152) >>> a/1 mpq(41,152) >>> 1/a mpq(152,41) >>> -a mpq(-41,152) >>> abs(-a) mpq(41,152) >>> _g.qsign(b-a) 1 >>> _g.qsign(b-b) 0 >>> _g.qsign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> an=a.numer(); ad=a.denom(); >>> an==0 or 1==a*_g.mpq(ad,an) 1 >>> bn=b.numer(); bd=b.denom(); >>> bn==0 or 1==b*_g.mpq(bd,bn) 1 >>> zn=z.numer(); zd=z.denom(); >>> zn==0 or 1==z*_g.mpq(zd,zn) 1 >>> (a+b) == _g.mpq(an*bd+ad*bn,ad*bd) 1 >>> (a+z) == _g.mpq(an*zd+ad*zn,ad*zd) 1 >>> (a+a) == _g.mpq(an*ad+ad*an,ad*ad) 1 >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpq(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpq(0) 1 >>> not a 0 >>> coerce(a,1) (mpq(41,152), mpq(1)) >>> coerce(1,a) (mpq(1), mpq(41,152)) >>> coerce(a,1.0) (mpq(41,152), mpq(1)) >>> coerce(a,_g.mpz(1)) (mpq(41,152), mpq(1)) >>> coerce(a,_g.mpf(1)) (mpq(41,152), mpq(1)) >>> a>1 0 >>> a>1.0 0 >>> a<1 1 >>> a<1.0 1 >>> a==1 0 >>> a==1.0 0 >>> cmp(a,1) -1 >>> cmp(1.0,a) 1 >>> long(1/a) 3L >>> long(-1/a) -3L >>> int(1/a) 3 >>> int(-1/a) -3 >>> ''' __test__['format']=\ r''' >>> str(a) '41/152' >>> repr(a) 'mpq(41,152)' >>> a==eval(repr(a),_g.__dict__) 1 >>> str(-a) '-41/152' >>> repr(-a) 'mpq(-41,152)' >>> (-a)==eval(repr(-a),_g.__dict__) 1 >>> _g.set_tagoff(0) 1 >>> a gmpy.mpq(41,152) >>> _g.set_tagoff(1) 0 >>> for i in range(1,7): ... for j in range(3,10): ... if _g.mpq(i,j) != _g.mpq("%d/%d"%(i,j)): ... print 'er1:',i,j; break ... aa=_g.mpq(i,j); ai=aa.numer(); aj=aa.denom() ... if aj!=1 and str(aa) != ("%d/%d"%(ai,aj)): ... print 'er2:',i,j,str(aa),("%d/%d"%(ai,aj)); break ... if aj==1 and str(aa) != ("%d"%ai): ... print 'er3:',i,j,str(aa),"%d"%ai; break ... if aj!=1 and repr(aa) != ("mpq(%d,%d)"%(ai,aj)): ... print 'er4:',i,j,repr(aa),("mpq(%d,%d)"%(ai,aj)); break ... if aj==1 and repr(aa) != ("mpq(%d)"%ai): ... print 'er5:',i,j,repr(aa),"mpq(%d)"%ai; break >>> fmo='_g.mpq('+a.numer().digits(16)+','+a.denom().digits(16)+')' >>> fmo '_g.mpq(0x29,0x98)' >>> eval(fmo)==a 1 >>> fmo='_g.mpq("'+a.numer().digits(30)+'/'+a.denom().digits(30)+'",30)' >>> fmo '_g.mpq("1b/52",30)' >>> eval(fmo)==a 1 >>> _g.qdigits(a,30) '1b/52' >>> a.digits(30) '1b/52' >>> _g.mpq(1000*1000*1000*1000L,23) mpq(1000000000000L,23) >>> _g.mpq(23,1000*1000*1000*1000L) mpq(23,1000000000000L) >>> _g.mpq(23L**10L,1000L**4L) mpq(41426511213649L,1000000000000L) >>> _g.qbinary('pep') Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: argument can not be converted to mpq >>> ''' __test__['binio']=\ r''' >>> ba=a.binary() >>> len(ba) 6 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 1 0 0 0 41 152 >>> _g.mpq(ba,256)==a 1 >>> ba == _g.qbinary(a) 1 >>> ba=(-a).binary() >>> len(ba) 6 >>> for i in range(len(ba)): ... print ord(ba[i]), ... if i==len(ba)-1: print ... 1 0 0 128 41 152 >>> _g.mpq(ba,256)==-a 1 >>> hash(a)==hash(_g.mpf(a))==hash(float(a)) 1 >>> hash(b)==hash(_g.mpf(b))==hash(float(b)) 1 >>> hash(-a)==hash(-_g.mpf(a))==hash(-float(a)) 1 >>> hash(-b)==hash(-_g.mpf(b))==hash(-float(b)) 1 >>> ''' __test__['power']=\ r''' >>> _g.mpq(2,3)**3 mpq(8,27) >>> _g.mpq(8,27)**_g.mpq('2/3') mpq(4,9) >>> _g.mpq(2,3)**-3 mpq(27,8) >>> _g.mpq(8,27)**_g.mpq('-2/3') mpq(9,4) >>> print float(_g.mpf('0.2')**2) 0.04 >>> print float(_g.mpf('0.2')**-2) 25.0 >>> _g.mpq(3)**3 == _g.mpz(3)**3 1 >>> (a**-7) == 1/(a**7) 1 >>> (b**5) == 1/(b**-5) 1 >>> ''' __test__['qdiv']=\ r''' >>> _g.qdiv(12,2) mpz(6) >>> _g.qdiv(12,5) mpq(12,5) >>> a is a.qdiv() 1 >>> a is a.qdiv(1) 1 >>> a is a.qdiv(2) 0 >>> x=a.numer() >>> x is _g.qdiv(x) 1 >>> x is _g.qdiv(x,1) 1 >>> x is _g.qdiv(x,2) 0 >>> y=_g.mpq(4,1) >>> y is y.qdiv() 0 >>> y == y.qdiv() 1 >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.8 pre-alpha (mpq functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with caching disabled" _g.set_qcache(0) sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_08_mpz.py --- # partial unit test for gmpy 0.8 mpz functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 0.8 r''' >>> filter(lambda x: not x.startswith('_'), dir(_g)) ['binary', 'bincoef', 'ceil', 'comb', 'denom', 'digits', 'divm', 'f2q', 'fac', 'fbinary', 'fdigits', 'fib', 'floor', 'fsign', 'fsqrt', 'gcd', 'gcdext', 'get_qcache', 'get_zcache', 'get_zconst', 'getbit', 'getprec', 'getrprec', 'gmp_version', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'lcm', 'legendre', 'lowbits', 'mpf', 'mpq', 'mpz', 'next_prime', 'numdigits', 'numer', 'popcount', 'qbinary', 'qdigits', 'qdiv', 'qsign', 'rand', 'reldiff', 'remove', 'root', 'scan0', 'scan1', 'set_callback', 'set_debug', 'set_fcoform', 'set_minprec', 'set_qcache', 'set_tagoff', 'set_zcache', 'set_zconst', 'setbit', 'sign', 'sqrt', 'sqrtrem', 'trunc', 'version'] >>> dir(a) ['_copy', 'binary', 'bincoef', 'comb', 'digits', 'getbit', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'legendre', 'lowbits', 'next_prime', 'numdigits', 'popcount', 'qdiv', 'remove', 'root', 'scan0', 'scan1', 'setbit', 'sign', 'sqrt', 'sqrtrem'] >>> ''' import gmpy as _g, doctest,sys __test__={} a=_g.mpz(123) b=_g.mpz(456) def factorize(x): r''' >>> factorize(a) [3, 41] >>> factorize(b) [2, 2, 2, 3, 19] >>> ''' import gmpy as _g savex=x prime=2 x=_g.mpz(x) factors=[] while x>=prime: newx,mult=x.remove(prime) if mult: factors.extend([int(prime)]*mult) x=newx prime=_g.next_prime(prime) for factor in factors: assert _g.is_prime(factor) from operator import mul assert reduce(mul, factors)==savex return factors __test__['elemop']=\ r''' >>> a+b mpz(579) >>> a-b mpz(-333) >>> a*b mpz(56088) >>> a/b mpz(0) >>> a%b mpz(123) >>> b+a mpz(579) >>> b-a mpz(333) >>> b*a mpz(56088) >>> b%a mpz(87) >>> divmod(a,b) (mpz(0), mpz(123)) >>> divmod(b,a) (mpz(3), mpz(87)) >>> -a mpz(-123) >>> abs(-a)==a 1 >>> pow(a,7) mpz(425927596977747L) >>> pow(a,7,b) mpz(99) >>> _g.sign(b-a) 1 >>> _g.sign(b-b) 0 >>> _g.sign(a-b) -1 >>> a.sign() 1 >>> (-a).sign() -1 >>> z=b-b; z.sign() 0 >>> ''' __test__['cmpr']=\ r''' >>> c=_g.mpz(a) >>> c is a 1 >>> c==a 1 >>> c>a 0 >>> c<a 0 >>> d=a._copy() >>> a is d 0 >>> a == d 1 >>> cmp(a,c) 0 >>> cmp(a,b) -1 >>> a>b 0 >>> a<b 1 >>> not _g.mpz(0) 1 >>> not a 0 >>> coerce(a,1) (mpz(123), mpz(1)) >>> coerce(1,a) (mpz(1), mpz(123)) >>> coerce(a,1.0) (123.0, 1.0) >>> _g.mpz(3.14) mpz(3) >>> _g.mpz(_g.mpq(17,3)) mpz(5) >>> _g.mpz(23L) mpz(23) >>> _g.mpz(-23L) mpz(-23) >>> x=1000*1000*1000*1000L >>> _g.mpz(x) mpz(1000000000000L) >>> ''' __test__['bitops']=\ r''' >>> ~a mpz(-124) >>> a&b mpz(72) >>> a|b mpz(507) >>> a^b mpz(435) >>> a<<1 mpz(246) >>> a>>1 mpz(61) >>> a<<-1 Traceback (innermost last): File "<pyshell#42>", line 1, in ? a<<-1 ValueError: Pympz_lshift negative shift count >>> a>>-2 Traceback (innermost last): File "<pyshell#43>", line 1, in ? a>>-2 ValueError: Pympz_rshift negative shift count >>> a<<0 mpz(123) >>> a>>0 mpz(123) >>> a.popcount() 6 >>> _g.popcount(b) 4 >>> a.hamdist(b) 6 >>> a.lowbits(5) mpz(27) >>> b.lowbits(5) mpz(8) >>> b.lowbits(5)==(b%32) 1 >>> a.lowbits(5)==(a%32) 1 >>> a.setbit(20) mpz(1048699) >>> a.setbit(0,0) mpz(122) >>> for i in range(8): ... print a.getbit(i), ... if i==7: print ... 1 1 0 1 1 1 1 0 >>> for i in range(10): ... print b.getbit(i), ... if i==9: print ... 0 0 0 1 0 0 1 1 1 0 >>> i=0 >>> while 1: ... j = a.scan0(i) ... print j, ... if j is None or j>31: ... print ... break ... else: i = j + 1 ... 2 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 >>> i=0 >>> while 1: ... j = a.scan1(i) ... print j, ... if j is None or j>31: ... print ... break ... else: i = j + 1 ... 0 1 3 4 5 6 None >>> n=_g.mpz(-(7+6*16+5*256+7*4092)) >>> i=0 >>> while 1: ... j = n.scan0(i) ... print j, ... if j is None or j>31: ... print ... break ... else: i = j + 1 ... 2 4 5 7 9 11 15 None >>> i=0 >>> while 1: ... j = n.scan1(i) ... print j, ... if j is None or j>31: ... print ... break ... else: i = j + 1 ... 0 1 3 6 8 10 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 >>> ''' __test__['format']=\ r''' >>> str(a) '123' >>> repr(a) 'mpz(123)' >>> hex(a) '0x7b' >>> oct(a) '0173' >>> _g.mpz('123') mpz(123) >>> _g.mpz('1001001011',2) mpz(587) >>> _g.mpz('1001001011',2).digits(2) '1001001011' >>> for i in range(2,37): ... print a.digits(i), ... if i%6==0: print ... 1111011 11120 1323 443 323 234 0173 146 123 102 a3 96 8b 83 0x7b 74 6f 69 63 5i 5d 58 53 4n 4j 4f 4b 47 43 3u 3r 3o 3l 3i 3f >>> print a.digits(37) Traceback (innermost last): File "<stdin>", line 1, in ? print a.digits(37) ValueError: base must be either 0 or in the interval 2 ... 36 >>> _g.set_tagoff(0) 1 >>> a gmpy.mpz(123) >>> _g.set_tagoff(1) 0 >>> _g.mpz('43') mpz(43) >>> _g.mpz('043') mpz(43) >>> _g.mpz('43',0) mpz(43) >>> _g.mpz('043',0) mpz(35) >>> _g.mpz('0x43',0) mpz(67) >>> _g.mpz('0x43') Traceback (innermost last): File "<pyshell#181>", line 1, in ? _g.mpz('0x43') ValueError: invalid digits >>> ''' __test__['binio']=\ r''' >>> ba=a.binary() >>> ba '{' >>> _g.mpz(ba,256) mpz(123) >>> _g.mpz(ba,256)==a 1 >>> _g.binary(123) '{' >>> z=_g.mpz('melancholy',256) >>> z mpz(573406620562849222387053L) >>> divmod(z,a) (mpz(4661842443600400182008L), mpz(69)) >>> for i in range(2,37): ... print i,z.numdigits(i), ... if i%6==0: print ... 2 79 3 50 4 40 5 35 6 31 7 29 8 27 9 25 10 24 11 23 12 23 13 22 14 21 15 21 16 20 17 20 18 19 19 19 20 19 21 18 22 18 23 18 24 18 25 18 26 17 27 17 28 17 29 17 30 17 31 16 32 16 33 16 34 16 35 16 36 16 >>> _g.numdigits(23) 2 >>> _g.numdigits(23,2) 5 >>> _g.numdigits(23,99) Traceback (most recent call last): File "<string>", line 1, in ? ValueError: base must be either 0 or in the interval 2 ... 36 >>> hash(a) 123 >>> hash(b) 456 >>> hash(z) -791330233 >>> _g.mpz(_g.binary(-123),256) mpz(-123) >>> long(_g.mpz(-3)) -3L >>> ''' __test__['number']=\ r''' >>> print a.sqrt(), b.sqrt() 11 21 >>> print a.sqrtrem(), b.sqrtrem() (mpz(11), mpz(2)) (mpz(21), mpz(15)) >>> for i in range(5): ... print a.root(i+1),b.root(i+1) ... (mpz(123), 1) (mpz(456), 1) (mpz(11), 0) (mpz(21), 0) (mpz(4), 0) (mpz(7), 0) (mpz(3), 0) (mpz(4), 0) (mpz(2), 0) (mpz(3), 0) >>> a.is_square() 0 >>> a.is_power() 0 >>> _g.is_square(99*99) 1 >>> _g.is_square(99*99*99) 0 >>> _g.is_power(99*99*99) 1 >>> _g.gcd(a,b) mpz(3) >>> _g.gcdext(a,b) (mpz(3), mpz(-63), mpz(17)) >>> _g.lcm(a,b) mpz(18696) >>> _g.fac(7) mpz(5040) >>> _g.fib(17) mpz(1597) >>> for i in range(10): ... print _g.bincoef(10,i) ... 1 10 45 120 210 252 210 120 45 10 >>> _g.divm(b,a,20) mpz(12) >>> _g.divm(a,b,100) Traceback (innermost last): File "<pyshell#184>", line 1, in ? _g.divm(a,b,100) ZeroDivisionError: not invertible >>> _g.divm(0,1,2) mpz(0) >>> a.invert(100) mpz(87) >>> b.invert(100) mpz(0) >>> _g.comb(3,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: binomial coefficient with negative k >>> _g.sqrt(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.sqrtrem(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: sqrt of negative number >>> _g.remove(3,-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: factor must be > 0 >>> _g.is_prime(3,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: repetition count for is_prime must be positive >>> _g.jacobi(10,3) 1 >>> _g.jacobi(10,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: jacobi's y must be odd prime > 0 >>> _g.legendre(10,3) 1 >>> _g.legendre(10,-3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: legendres's y must be odd and > 0 >>> _g.kronecker(10,3) 1 >>> _g.kronecker(10,-3) 1 >>> a=1000000L**2 >>> b=a+1 >>> _g.jacobi(a,b) 1 >>> _g.legendre(a,b) 1 >>> _g.kronecker(a,b) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Either arg in Kronecker must fit in an int >>> f=_g.mpf(3.3) >>> f.setprec(-1) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: n must be >=0 >>> _g.rand('init',-1) >>> _g.rand('init',-7) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: size must be in 1..128 >>> _g.rand('init',200) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: size must be in 1..128 >>> _g.rand('qual') 32 >>> _g.rand('floa',-7) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: 'floa' needs arg>=0 ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.8 pre-alpha (mpz functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache(), _g.get_qcache(), ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print "Repeating tests, with caching disabled" _g.set_zcache(0) _g.set_zconst(0,0) sav = sys.stdout class _Dummy: def write(self,*whatever): pass try: sys.stdout = _Dummy() doctest.testmod(thismod, report=0) finally: sys.stdout = sav if chat: print print "Overall results for cvr:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: gmpy_test_08_rnd.py --- # partial unit test for gmpy 0.8 rand functionality # relies on Tim Peters' "doctest.py" test-driver # test-version 0.8 r''' >>> r <built-in function rand> >>> ''' import gmpy as _g, doctest,sys __test__={} r = _g.rand __test__['rand']=\ r''' >>> r('init',20) >>> r('seed',1234) >>> for i in range(5): ... print r('next',100), ... if i==4: print ... 21 75 63 28 27 >>> alis=list("proktelnu") >>> for i in range(10): ... r('shuf',alis) ... print ''.join(alis) ... rtoulpnke eoturlknp plnuetokr ekoprulnt kpoutnrel rutoneklp ukeptnorl onkrlpteu lknteropu enrkutlpo >>> sav=r('save') >>> print sav 774447212137 >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... elnuortpk enutolpkr eropulntk plroutenk ekonrtplu >>> r('seed',sav) >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... epkruotln ekrtuplno eoulrpktn lpourtekn enukotlpr >>> r('seed',sav) >>> for i in range(3): ... print float(r('floa')) ... 0.44833278656 0.547296524048 0.895370483398 >>> r('seed',sav) >>> for i in range(3): ... print float(r('floa',6)) ... 0.484375 0.90625 0.75 >>> r('seed',sav) >>> for i in range(3): ... print _g.f2q(r('floa',6),-6) ... 15/31 9/10 3/4 >>> r('seed',sav) >>> for i in range(3): ... print _g.f2q(r('floa',6)) ... 31/64 29/32 3/4 >>> r('seed',sav) >>> for i in range(5): ... r('shuf',alis) ... print ''.join(alis) ... elnorutpk enotrlpku eurpolntk plurotenk ekrnutplo >>> ''' def _test(chat=None): if chat: print "Unit tests for gmpy 0.8 pre-alpha (rand functionality)" print " running on Python",sys.version print print "Testing gmpy %s (GMP %s) with default caching (%s, %s..%s)" % ( (_g.version(), _g.gmp_version(), _g.get_zcache() ) + _g.get_zconst()) thismod = sys.modules.get(__name__) doctest.testmod(thismod, report=0) if chat: print print "Overall results for rnd:" return doctest.master.summarize(chat) if __name__=='__main__': _test(1) --- NEW FILE: timing1.py --- import gmpy, time def timedsum(n, zero): start=time.clock() tot=zero for i in range(n): tot+=i stend=time.clock() return type(zero), stend-start, tot def timedmul(n, one): start=time.clock() tot=one for i in range(n): tot*=(i+1) stend=time.clock() return type(one), stend-start, tot def test(n=10*1000): print "Sum of %d items of various types:" % n for z in 0L, 0.0, gmpy.mpz(0), gmpy.mpf(0): tip, tim, tot = timedsum(n, z) print " %5.3f %.0f %s" % (tim, float(tot), tip) print "Mul of %d items of various types:" % n for z in 1L, 1.0, gmpy.mpz(1), gmpy.mpf(1): tip, tim, tot = timedmul(n, z) print " %5.3f %s" % (tim, tip) if __name__=='__main__': test() --- NEW FILE: timing2.py --- import gmpy, time def timedfib(n, zero): start=time.clock() a=zero; b=a+1 for i in range(n): a,b=b,a+b stend=time.clock() return type(zero), stend-start, a def timedfibsp(n, one): start=time.clock() result=gmpy.fib(n) stend=time.clock() return type(one), stend-start, result def test(n=10*1000): print "%dth Fibonacci number of various types:" % n for z in 0L, gmpy.mpz(0), gmpy.mpf(0): tip, tim, tot = timedfib(n, z) print " %5.3f %s %s" % (tim, gmpy.fdigits(tot,10,6), tip) tip, tim, tot = timedfibsp(n, 1) print " %5.3f %s %s" % (tim, gmpy.fdigits(tot,10,6), "gmpy.fib") if __name__=='__main__': test() --- NEW FILE: timing3.py --- import gmpy as _g import time print "Typical expected results",""" D:\PySym>python timing.py Factorial of 10 took 9.97333181359e-005 (7 digits) Fibonacci of 10 took 9.88952230255e-005 (2 digits) Factorial of 100 took 0.000121523791006 (159 digits) Fibonacci of 100 took 9.05142719216e-005 (21 digits) Factorial of 1000 took 0.00173569497361 (2568 digits) Fibonacci of 1000 took 0.000138285693214 (209 digits) Factorial of 10000 took 0.0619989238859 (35660 digits) Fibonacci of 10000 took 0.000744228458022 (2090 digits) Factorial of 100000 took 4.44311764676 (456574 digits) Fibonacci of 100000 took 0.022344453738 (20899 digits) Factorial of 1000000 took 152.151135367 (5565709 digits) Fibonacci of 1000000 took 0.670207059778 (208988 digits) """ for i in (10,100,1000,10000,100000,1000000): start=time.clock() x=_g.fac(i) stend=time.clock() print "Factorial of %d took %s (%d digits)" % ( i, stend-start, x.numdigits()) start=time.clock() x=_g.fib(i) stend=time.clock() print "Fibonacci of %d took %s (%d digits)" % ( i, stend-start, x.numdigits()) |
From: Gustavo N. <nie...@us...> - 2001-12-11 10:30:04
|
Update of /cvsroot/gmpy/gmpy/doc In directory usw-pr-cvs1:/tmp/cvs-serv30377/doc Added Files: gmpydoc.txt index.html Log Message: Added files to repository. --- NEW FILE: gmpydoc.txt --- gmpy module -- a complete Python 2 interface for GMP 3.1 (including a Win32/MSVC++ build). *Notes on history of file gmpydoc.txt* Notes for version 0.1 (pre-alpha), first one placed on sourceforge -- A. Martelli, al...@ya..., 00/11/06. Edited for version 0.2 (still pre-alpha), bugfixes & minor performance tweaks, 00/11/15 -- many thanks to Pearu Peterson for his contributions re 0.1 -> 0.2! Edited for version 0.3 (ditto) -- cleanup, exposing more mpz functions (almost all there...!), large performance-tweaks via caching (tx to PP for the inspiration!), some unit-tests -- **NEED MANY MORE TESTS FOR 0.4**!!! -- 00/11/18. Small edits for version 0.4 (ditto) -- just a couple more functions, and minor error-corrections -- 11/24. (Added docstrings in 0.4; would be nice to build a doc of some kind automatically from ONE place...). Edited for version 0.5 (ditto) -- documented the new functionality (mostly mpq; also: random, jacobi/legendre/ kronecker), minor cleanups & corrections -- 11/30. Editing for versions 0.6 (12/07), 0.7 (12/16), 0.8 (12/26): documented new functionalities, minor cleanups & corrections each time. Very minor editing for version 0.9 (2001/01/25). *Acknowledgments* Based on previous versions of gmpmodule.c (for earlier Python and GMP releases) by AMK and Niels Möller (only removed feature: conditional possibility to substitute this implementation in place of Python's built-in longs; Lots and lots of added features). Special thanks are due to Pearu Peterson for his MANY important inputs on design aspects, performance tweak suggestions, and bug discoveries. Thanks also to Keith Briggs for his precious feedback, and to Tim Peters and Fredrik Lundh for suggestions. *Installation and testing* Pre-requisites: Python 2, GMP 3.1.1 (see later for Win32). To build gmpy from sources, unpack the sources zipfile (gmpy-sources-09.zip, for example, for release 0.9) into a new, dedicated directory; cd to that directory (from any shell on Unix/Linux, from a 'Dos box' aka 'command box' on Windows, etc), and run the command: python setup.py install the DistUtils that come with Python 2 take over and build and install the gmpy module for you. On Unix, GMP 3.1.1 must have been previously and separately installed; on Win32, the gmp.lib and gmp.h supplied (in the gmpy-win32 package, only; file gmpy-win32-library-06.zip, please unzip it in the same directory as the sources) can be used (the linker will give two warnings, but they are innocuous ones -- please ignore them). GMP 3.1.1 for MSVC++ 6 is found at: ftp://ftp.whiterose.net/pub/lundman. Distutils are not yet supported for the pre-built gmpy.pyd for windows, that comes in the gmpy-win32-binary-08.zip file -- just move the gmpy.pyd it contains to c:\Python20 (or wherever you have your Python 2.0 installation). The sources zipfile also contains this file (gmpydoc.txt), an example C source file for a separate module that uses the C-API of gmpy to interoperate with it (the .pyd for that example module, for Win32, is also in -binary-08.zip), a copy of the index.html for the gmpy sourceforge site, and python scripts that exemplify, show the performance of, and test, some functionality of the gmpy module. To test the installation, ensure Tim Peter's doctest.py is in a directory in the PYTHONPATH (a copy is enclosed in the gmpy sources zipfile), and, in the directory where you unpacked the sources, run at the command prompt: python gmpy_test_08.py Expected output is something like (details may differ!): """ Unit tests for gmpy 0.8 pre-alpha on Python 2.0 (#8, Oct 16 2000, 17:27:58) [MSC 32 bit (Intel)] Testing gmpy 0.8.0c (GMP 3.1.1), default caching (20, 20, -2..11) gmpy_test_08_cvr 120 tests, 0 failures gmpy_test_08_rnd 21 tests, 0 failures gmpy_test_08_mpf 137 tests, 0 failures gmpy_test_08_mpq 122 tests, 0 failures gmpy_test_08_mpz 156 tests, 0 failures 26 items passed all tests: [26 lines snipped] 556 tests in 26 items. 556 passed and 0 failed. Test passed. """ Should you wish to test some specific portion, please note that each of the various modules listed at the start can also be run independently, if so desired: python gmpy_test_08_mpq.py python gmpy_test_08_mpz.py and so on, expecting output analogous to the above example. The key issue is the 'Test passed' line at the end of each run! *PLEASE* report any failures to gmpy's maintainer, with any details you can supply on your machine, on your OS, and on your installation of GMP, gmpy, Python 2, and any other relevant issue (your C/C++ compiler & libraries, &c). *THANKS* in advance -- bug reporting and feedback is your key contribution to the gmpy project! (Reports of any _successful_ installations will also be welcome, if it's accompanied by enough details -- again, THANKS in advance!). *General notes on gmpy* gmpy exposes to Python three types of numbers that are implemented in GMP 3: mpz unlimited-precision integers mpq unlimited-precision rationals mpf extended-precision floats See GMP documentation for general descriptions of them! GNU MP Home Page: http://www.swox.com/gmp/ Licensing: since GMP is distributed under the LGPL, so, therefore, is also gmpy. IANAL, but, summarizing, this means: other _libraries_ that are derived from gmpy must also be distributed under the LPGL (or full-GPL), as must any modifications/changes/additions to gmpy; but, no such restriction applies on code that just _uses_ these modules/libraries (such gmpy-using code may thus be licensed in whatever way is desired). Warranty: NONE -- as usual for open-source software (see the detailed disclaimers in GMP's license)! *gmpy.mpz -- unlimited-precision integral numbers* gmpy.mpz objects have the full arithmetic abilities of Python longs (in the future, there may be mutable versions of them [for performance], but NOT yet). Specifically, arithmetic operators + and - (unary and binary), *, / (truncating), %, **, bitwise operators such as &, |, ^, <<, >>, ~, and builtin Python functions such as divmod and pow, all work as expected on mpz objects (basically, the same way as on builtin Python longs, except that the speed can be quite different -- from 'a bit slower' for some things, up to MUCH faster for others [such as multiplication of HUGE numbers]). Mixed-operand arithmetic is supported: the other operand (which must be a number of some kind) is coerced to a gmpy.mpz, unless it's of a floating type, in which case the .mpz object is coerced to that floating type instead (or mpq, or complex, ditto). An mpz object can be built by passing to the gmpy.mpz constructor function any Python number, another mpz (this *shares* object identity, does *not* copy it), a mpq or mpf (which gets truncated, as also a Python float does), or a string (representing the number in base 10). gmpy.mpz can also be called with TWO arguments: the first one a string representing the number in base N, the second one, the integer N. N can be between 2 and 36, or it can be 256, which implies that the string is the _portable binary gmpy representation_ of the mpz (as produced by method .binary() of mpz objects, and function gmpy.binary() of the module). An N of 0 is also accepted, and means the string is interpreted as decimal, unless it starts with 0x (then, hexadecimal) or 0 (then, octal). When N=16 a starting a leading '0x' is also accepted, but not required; leading 0's are always accepted and ignored (they do NOT mean the rest is taken as octal!) if the base N is explicitly given as a Python int, or if it's omitted (and defaults to 10). *NOTE* that the trailing-L in a Python's "long" string representation is NOT accepted in the string argument to gmpy.mpz()! (Please note that all from-string transformations are performed by GMP, and thus follow slightly different conventions from normal Python ones, specifically with regard to input strings containing spaces). An mpz object can be transformed into a Python number with the usual Python built-in functions (int, long, float); it can also be formatted as an octal or hex string with Python built-in functions oct and hex. mpz objects also support the hash built-in function, and can thus be used as dictionary keys; for any Python int or long N, hash(mpz(n)) and hash(n) are equal. Other operations on mpz objects are all exposed as functions of module gmpy, and some, also, as methods of mpz objects. Unless otherwise noted, arguments to the following gmpy module functions are coerced to mpz (unless already of mpz type), and values returned from either functions or modules are also of mpz type. gmpy.binary(x) or x.binary(): returns a portable binary representation (base-256 little endian) of a non-negative mpz object, suitable for saving into a file (or db, whatever) -- this string can later be passed as the first argument to function gmpy.mpz (with a second argument with value 256) to reconstruct a copy of the original mpz object. *NOTE*: binary format used by gmpy release 0.7 and later is not compatible with that of 0.6 and earlier, as the latter, as a design limitation, could not represent any mpz number that was < 0. gmpy.digits(x[,base]) or x.digits([base]): returns a string representing x in the given base (between 2 and 36, defaulting to 10 if omitted or zero); a leading '-' will be present if x<0, but no leading '+' if x>=0. If base is 8 or 16, a decoration of a leading '0' (or, respectively, '0x') is present (after the '-' sign, if the number is negative). gmpy.numdigits(x[,base]) or x.numdigits([base]): returns an approximation to the number of digits for x in the given base (result is either exact [guaranteed if base is a power or 2] or 1 more than actual length; space for a "sign", or leading decorations of '0' or '0x', is NOT considered). Base must be between 2 and 36, defaulting to 10 if omitted or zero. gmpy.sign(x) or x.sign(): -1, 0, or 1, depending on whether x is negative, zero, or positive. gmpy.divm(a, b, M): x such that b*x == a modulo M (will raise a ZeroDivisionError exception if no such x exists). gmpy.fac(x): factorial of x (takes O(x) time; x must be an ordinary Python non-negative integer!) gmpy.fib(x): x-th Fibonacci number (takes O(x) time; x must be an ordinary Python non-negative integer). gmpy.gcd(a,b): greatest common divisor of a and b (an mpz, >= 0). gmpy.gcdext(a, b): a tuple (g,s,t) such that g==gmpy.gcd(a,b) and g == a*s + b*t (g, s and t are all mpz). gmpy.lcm(a,b): least common multiple of a and b (an mpz, >= 0). gmpy.is_square(x) or x.is_square(): 1 iff x is a perfect square, else 0 (returns Python int). gmpy.is_power(x) or x.is_power(): 1 iff x is a perfect power (i.e., there exist a, b such that a**b==x and b>1), else 0 (returns Python int). gmpy.is_prime(x [, count]) or x.is_prime([count]): 2 if x is _certainly_ prime, 1 if x is _probably_ prime, 0 if x is _certainly_ composite; count defaults to 25 (probability of primality, if is_prime returns 1, is guaranteed to be at least 1 in 2**count). Returns Python int. NOTE: GMP believes negative numbers can be primes, and gmpy just reflects this stance (cfr discussion at http://www.utm.edu/research/primes/notes/faq/negative_primes.html) gmpy.next_prime(x) or x.next_prime(): returns mpz that is the lowest prime > x; *probabilistic* algorithm for prime-determination (see is_prime). gmpy.sqrt(x) or x.sqrt(): integer square-root of non negative number (truncating, unless is_square(x)). gmpy.sqrtrem(x) or x.sqrtrem(): tuple (s,t) such that s==gmpy.sqrt(x) and x==s*s+t. (s and t are mpz, >= 0). gmpy.root(x,n) or x.root(n): tuple (s,b) such that s is the truncated nth-root of x, b!=0 if s is the _exact_ root (i.e. x==s**n); n must be an ordinary Python int, >0. (s is an mpz, b a Python int). gmpy.bincoef(x, N) or x.bincoef(N): binomial coefficient "x over N"; N must be an ordinary Python int, >=0! (x may be < 0 , see Knuth vol 1, sect 1.2.6, part G). [Also known as: gmpy.comb(x, N) or x.comb(N), since the binomial coefficient is also the number of different combinations of x objects taken N at a time, with ordering ignored]. gmpy.remove(x, f) or x.remove(f): "remove factors": returns a two-element tuple (y,m), where y, an mpz, is x without any factor of f, and m (an ordinary Python int) is the multiplicity of f in x (e.g.: m==0 and y==x unless x%f==0; and in any case, it's ensured that x==y*(f**m) and that y%f!=0). gmpy.invert(x, m) or x.invert(m): modulo-inverse; returns an y such that x*y mod m = 1, if one exists, else 0 (returns an mpz in either case). gmpy.lowbits(x, n) or x.lowbits(n): returns the n lowest bits of x (n must be an ordinary Python int, >0; returns an mpz, >= 0). Note that x<0 is assumed to be in 2's complement notation (i.e., "extended on the left" with infinite 1-bits); so, for example, for any n>0, gmpy.lowbits(-1,n) returns an mpz>0 with the lowest n bits set to 1, i.e., (2**n)-1. gmpy.setbit(x, n, v) or x.setbit(n, v), n being a bitindex (0 and up, ordinary Python int) and v an int value (0 or 1, default 1): returns a copy of x with bit n set to v (mpz's are not mutable -- yet...!). [Any value v != 0 is equivalent to v=1, i.e., the bit is 'set'; so, for example, gmpy.setbit(0,n,-4) for any n>=0 returns an mpz worth 2**n]. gmp.getbit(x, n) or x.getbit(n), n being a bitindex (0 and up, ordinary Python int): returns an int which is 0 or 1, same as the value of bit n of x. (See note on gmpy.lowbits for x<0). gmpy.scan0(x [, n]) or x.scan0([n]): returns the bit index of the next 0-bit starting at bit n (default 0); n must be an ordinary Python int, >=0; returns a Python int (None if there is no such bit-index, which can only happen for an x<0, which notionally is extended with infinite 1-bits). gmpy.scan1(x [, n]) or x.scan1([n]): returns the bit index of the next 1-bit starting at bit n (default 0); n must be an ordinary Python int, >=0; returns a Python int (None if there is no such bit-index, which can only happen for an x>=0, which notionally is extended with infinite 0-bits). gmpy.popcount(x) or x.popcount(): returns the "population count" (number of bits set to 1) of x; note that this is 'infinite' for x<0 (-1 is then returned). Returns a Python int. gmpy.hamdist(x,y) or x.hamdist(y): returns the hamming-distance |x,y| if both >=0 (returns -1 if either or both <0) (the hamming distance is defined as: the number of bit-positions in which the two numbers differ). Returns a Python int. Same as gmpy.popcount(x^y). gmpy._copy(x) or x._copy(): provide a separate copy of x (only relevant for future mutability of mpz..!). *gmpy module-level setting functions* [NOTE: the overall architecture of these functions is due to be reworked soon, not backwards-compatibly]. gmpy.set_debug(flag): turns on/off debugging output from the gmpy module (returns previous setting). [Only of interest to develop/debug gmpy itself!] Argument must be an ordinary Python int: debug is set on if flag!=0, off if flag==0. Returns a Python int (0 or 1, the _previous_ setting). gmpy.set_tagoff(flag): turns off/on the 'gmpy.' prefix to the "tag" that repr() places around the string-representation of gmpy objects (returns a Python int, 0 or 1, the previous setting). gmpy. get_zcache(), set_zcache(N), get_zconst(), set_zconst(N,M), get_qcache(), set_qcache(N)...: *internal tweaks/experimental stuff*, please don't use them unless you've read the C sources and understand what they do! Not further documented here (docstrings for these functions in gmpy may give a little more detail). *gmpy.mpq -- unlimited-precision rational numbers* gmpy.mpq objects have a subset of the arithmetic abilities of Python floats (in the future, mutable versions will also be supplied, but, NOT YET!), but represent arbitrary rational numbers with no loss of precision whatsoever. [Note, in particular, that raising-to-power works only without a modulo, and, if the exponent is a fraction with a denominator D (or gets converted to one), the base must be an exact D-th power, or the operation fails raising a ValueError exception]. Mixed-operand arithmetic is supported: the other operand is coerced to a gmpy.mpq. NOTE: the % operator and the divmod built-in function are NOT supported. mpq objects also support the hash built-in function, and can thus be used as dictionary keys; for any Python int or long N, hash(mpq(n)) and hash(n) are equal. A mpq object has a _numerator_ and a _denominator_; they can be obtained by calling on an mpq object the methods .numer() and .denom() -- each method has no arguments and returns an mpz (the denominator will always be >0; the numerator can be any; also, the numerator and denominator never have any common factors; mpq corresponding to integers, including 0, always have a denominator of exactly 1). An mpq is built by passing to the gmpy.mpq constructor function any Python number, another mpq (this *shares* object identity, does *not* copy it), a mpf or mpz, or a string (representing the number in base 10). [If an mpf or float argument is passed, the mpq is built from it with an 'optimal' approach based on a Stern-Brocot tree; see also the f2q method of mpf objects, and gmpy.f2q module-level function, which differ from explicit mpq-construction in that it can return an mpz if the mpq's denominator would be 1]. gmpy.mpq can also be called with TWO arguments: the first one a string representing the number in base N, the second one, the integer N. N can be between 2 and 36, or, it can be 256, which implies that the string is the _portable binary gmpy representation_ of the mpq (as produced by method .binary() of mpq objects, and function gmpy.qbinary() of the module). gmpy.mpq is typically called with a string that contains a '/' character: the digits before it will then be taken as the numerator, those after it, as the denominator (the resulting number is normalized: denominator>0, no common factors). A ZeroDivisionError is raised if the denominator thus supplied is zero; a ValueError, if the string is otherwise invalid (e.g., '/3' or '3/'). Hex and octal representations are supported if the base N is given as 0; see above qmpy.mpz; for example, mpq('0x13/011',0) is the same as mpq(19,9). gmpy.mpq can also be called with two number arguments: the first one is taken as the numerator, the second one as the denominator (the resulting number is normalized: denominator>0, no common factors). A ZeroDivisionError is raised if the denominator thus supplied is zero. Other operations on mpq objects are all exposed as functions of modules gmpy, and some, also, as methods of mpq objects: gmpy.qbinary(x) or x.binary(): returns a portable binary representation of any mpq object (there are no restrictions, e.g. on the number's sign). gmpy.qsign(x) or x.sign(): -1, 0, or 1, depending on whether x is negative, zero, or positive. gmpy.qdiv(x[,y]) or x.qdiv([y]), which is _also_ supplied as a method on mpz and mpf objects (which are implicitly converted to mpq's in this case): return x/y (or just x, if y is absent), as an mpz if possible (==if a resulting mpq would have a denominator of 1), else as an mpq (with a denom of greater than 1). The functions are optimized, so that, if x is an mpz and y is absent or 1, or if x is an mpq with a denom>1 and y is absent or 1, then the same object-identity as x is returned, so that the operation is very fast. In other words, gmpy.qdiv only ever takes substantial time if it DOES have an important job to perform, and can thus be called rather freely, even in loops, to 'normalize' numeric results. Specifically, please note that, for an x that is an mpq, x.qdiv() returns either x, if x.denom()==1, or else the same mpz as x.numer() would return; if x is an mpz, x.qdiv() returns x (so it can be used polymorphically on an x that can be either, without any performance hit). *gmpy.mpf -- variable-precision floating numbers* gmpy.mpf objects have a subset of the arithmetic abilities of Python floats (in the future, mutable versions will also be supplied, but, NOT YET!). Mixed-operand arithmetic is supported: the other operand is coerced to a gmpy.mpf, except that, if the other operand is an mpq, then both are coerced to mpq. NOTE: trigonometric and exponential functionalities on mpf objects are NOT currently supported [GMP 3.1.1 has none; waiting to expose the MPFR extensions to GMP.] mpf objects also support the hash built-in function, and can thus be used as dictionary keys; for any Python float X, hash(mpf(x)) and hash(x) are equal. Each mpf object has a _precision_ -- a number of bits of precision to which values are stored in it. The precision of all newly generated mpf's is at least that set at module level via module function gmpy.set_minprec(n); a specific mpf's precision can be set to >= n bits by x.setprec(n); it can be queried (the exact current number of bits of precision is returned) by x.getprec() or gmpy.getprec(x). The granularity of precision of current MPF's is rough; exact precision setting is one of MPFR's enhancements. To get the actual precision that was _requested_ for a given mpf object, x.getrprec() and gmpy.getrprec(x) are also supplied -- the value returned from getprec will always be greater than, or equal to, the one returned from getrprec. An mpf is built by passing to the gmpy.mpf constructor function any Python number, another mpf (this *shares* object identity, does *not* copy it -- unless specific precision is requested for the resulting mpf, see later), a mpq or mpz, or a string (representing the number in base 10, possibly with decimal point and/or exponent). If gmpy.mpf is called with a float argument, the exact steps used in conversion depend on the setting of module level option fcoform (set by gmpy.set_fcoform()). If it's None, the float number is converted 'exactly' to an mpf (which often leaves spurious trailing bits from literals). If fcoform is a string, it's used as the format (left operand of %) in a formatting operation (with the float being transformed as the right operand), and the resulting intermediate string is the one that actually gets transformed to mpf (this normally gives good results with formats somewhere between '%.12e' and '%.16e', depending on the actual precision of the float being transformed). This also applies to _implicit_ conversions of float to mpf, as invoked for mixed-mode arithmetic or when gmpy functions expecting an mpf argument are called with a float argument (a string could not be passed _explicitly_ here -- an explicit mpz() around it would be needed -- but it's OK if a float gets _implicitly_ converted-to-mpf-via-string in these cases, through the fcoform mechanism). An optional second argument can always be supplied to gmpy.mpf, whether the first argument is a numner or a string; if supplied, it must be a Python int, >=0. If absent or 0, the precision of the mpf that is generated is determined by default depending on the input argument (in many cases, it's the number of significant bits in machine-floats; e.g., 53 on machines using IEEE 64-bit floating point). If the second argument is supplied and > 0, it's used as the requested-precision for the resulting mpf, ignoring the bits-of-precision held or implied by the first argument. Note, that if x is an mpf with n bits of precision, gmpy.mpf(x,m) will be able to return the same object identity as x if, and only if, m==n; else, a new mpf object of the requested precision will be generated. Note that, in arithmetic operations, the bits of precision of the result are generally set to the _lowest_ number of bits-of-precision of all the operands involved. gmpy.mpf can also be called with *3* arguments: the first one a string representing the number in base N, the second one the bits of precision requested (or 0 to accept the default determination of the bits), the third one, the integer N. N can be between 2 and 36, or, it can be 256, which implies that the string is the _portable binary gmpy representation_ of the mpf (as produced by method .binary() of mpf objects, and function gmpy.fbinary() of the module). (Hex and octal decorations are *not* supported here; an N of 0 is totally equivalent to one of 10). Note that therefore, if a reasonable fcoform is set, two constructor calls such as gmpy.mpf(3.4) and gmpy.mpf('3.4') will produce the same mpf object, although the second way is faster (and does not depend on the module-level fcoform setting) and recommended. Other operations on mpf objects are all exposed as functions of modules gmpy, and some, also, as methods of mpf objects: gmpy.fbinary(x) or x.binary(): returns a portable binary representation of any mpf object. gmpy.fdigits(x[,args...]) or x.digits([args]): returns a string representing x. Arguments (must currently be passed positionally, if at all) are...: base: number-base (between 2 and 36), default 10 digits: how many digits are requested (default 0, "all of them" within x's precision; fewer than requested may be obtained, if fewer available) minexp: minimum exponent for which the number is still to be formatted in integer.fraction form (it's formatted as fraction-exponent form if exponent is lower than minexp), default 0 maxexp: maximum exponent for which the number is still to be formatted in integer.fraction form (it's formatted as fraction-exponent form if exponent is higher than maxexp), default -1 option: bitmask argument, default 0 (no options) Note that, by default, the formating is in fraction- and-exponent form: [<sign>]<digit>.<digits><marker><signed exponent> sign is '-' if x is negative, omitted if x>=0 <marker> is 'e' for base<=10, otherwise '@' the signed exponent (sign omitted if exponent>=0) is always expressed in base 10, whatever the base used for the significand's digits. If option's bit 1 is set, the whole result string is enclosed between "gmpy.mpf('" at the start and "')" at the end, so it can be subject to eval to recover an approximation of the original number (depending on the settings of gmpy.set_tagoff(), the starting tag may actually be shortened to just "mpf('"). The precision, in bits, is also output in this case, just before the ')', separated from the "first argument to gmpy.mpf" by a comma character (it is the same number as returned by .getrprec). If option's bit 2 is set, then minexp, maxexp, and option's bit 1, are ignored: the result is a tuple of 2 objects: first, a string made up of all the digits (and maybe a leading - sign) and nothing else; second, an integer that is the exponent to use. This can be used by Python code that wants finer-grained control on resulting string format. gmp.reldiff(x,y) or x.reldiff(y): returns the relative difference between x and y, a non-negative mpf roughly equal to abs(x-y)/((abs(x)+abs(y))/2). gmpy._fcopy(x) or x._copy(): provide a separate copy of x (only relevant for future mutability of mpf..!). gmpy.fsign(x) or x.sign(): -1, 0, or 1, depending on whether x is negative, zero, or positive. gmpy.f2q(x) or x.f2q(): like gmpy.mpq(x), but, like qdiv, will return an mpz (instead of, as normally, an mpq), if the mpq's denominator would be 1. gmpy.fsqrt(x) or x.sqrt(): square-root of non negative number x. gmpy.set_fcoform([x]): sets or resets the format with which to build the intermediate-string to be used for float->mpf conversion. If x is None, or is absent, then the format is reset, and such conversions proceed 'directly'. If x is a Python int, it must be between 1 and 30, and is used as the number of digits in the format string '%.<x>e' (for example, set_fcoform(12) will set the format string for float-conversion to '%.12e'). Else, x must be a Python string usable as: x%f to format a float object f in some suitable way. set_fcoform also returns the previous setting of this option, None or a string. (See also the paragraph above about the float->mpf conversion mechanics, which gives more details about the way in which this format string is used by gmpy). *Experimental: function gmpy.rand* Since gmpy 0.5, the linear congruential random number generator of GMP is exposed via gmpy (with some modest added-value functionality) through function gmpy.rand. A couple options were added in 0.6. This will be refactored into separate functions in some future release. Its first parameter is a string 'opt' (4-characters, lowercase) which determines the exact functionality; it normally has a second paramenter 'arg' (which is optional for most values of 'opt') and may return either None or a significant value (an mpz, except for opt='floa', when an mpf is returned). gmpy.rand('init') Initialize the random-generator state (this is _implicitly_ called by other options of gmpy.rand, if needed, but should be explicitly called) to ensure 32 bits' randomness per each generation ('throw'). Returns None. gmpy.rand('init', arg) ditto, but ensure 'arg' bits of randomness (arg being an int between 1 and 128). This tweaks the linear congruential parameters according to the number of needed bits (it may be faster to generate just the needed number of 'good' bits). Returns None. gmpy.rand('qual') returns the current 'quality of random numbers' (the arg value passed to 'init', with a default of 32), or 0 if random number generation is not inited yet. [ignores arg, if present] gmpy.rand('seed', arg) set the current random-seed to 'arg', an mpz (or coerced to mpz). Returns None. gmpy.rand('seed') set the current random-seed 'randomly' in its turn (uses C-level function 'rand()'). Returns None. gmpy.rand('save') returns the current random-seed (an mpz) so that it can be saved (e.g. for program checkpointing) and later restored via a gmpy.rand('seed', x) call. [ignores arg, if present] gmpy.rand('next') returns a uniformly distributed random number in the range 0:2**31 (note that the UPPER end is EXCLUDED) and advances the random-number gneration by 1 step. (Basically, returns '31 random bits', if the current quality of the generator is at least 31; for lower-quality generators, upper bits tend to be "better" than less significant ones). gmpy.rand('next',arg) returns a uniformly distributed random number in the range 0:arg (note that the UPPER end is EXCLUDED) and advances the random-number generation by 1 step. Value returned is integral (mpz). gmpy.rand('floa',arg) returns a uniformly distributed random number in the range 0:1 (note that the UPPER end is EXCLUDED), with arg meaningful bits (default, if arg is 0, is current 'quality'), and advances the random-number generation by 1 step. Value returned is floating-point (mpf). gmpy.rand('floa') returns a uniformly distributed random number in the range 0:1 (note that the UPPER end is EXCLUDED), with as many meaningful bits as the current 'quality', and advances random-number generation by 1 step. Value returned is floating-point (mpf). gmpy.rand('shuf',arg) randomly shuffles mutable-sequence 'arg' (normally a list), in a way that ensures all permutations are equally likely. It advances random-number generation by len(arg)-1 steps. Returns None. *Experimental: the callbacks-facility* Since gmpy 0.8, gmpy exposes 'callback' facilities to help client-code personalize the handling of what, in pure-gmpy, would be error-cases. This is mostly intended for the use of Pearu Peterson's PySymbolic package, and is not currently documented (nor tested) in great detail for general use. You are welcome to contact gmpy's maintainer directly (and/or study gmpy's C sources:-) if you think you may have use for this facility, or are interested in doing something similar in other C modules for Python use -- it IS an interesting and reasonably novel approach. To summarize: with gmpy.set_callback(name, callable), client-code may set a Python callable as a callback for gmpy in a set of situations determined by the string 'name'. For example, gmpy.set_callback('ZD', myfun) sets 'myfun' as the callback that gmpy is to use in 'zero-division' situations. When gmpy is about to raise a ZeroDivision error, it checks if the 'ZD' callback is set; if so, then, instead of raising the exception itself, it delegates everything to the callback in question, passing it the name of the gmpy function involved, the arguments it was called with, and the error-string gmpy would use if it did raise the error. It's up to the callback to either raise a ZeroDivision itself, OR return some special object to map this situation -- for example, PySymbolic may return an 'infinity' object and suppress the error. Basically, this works around Python's (excellent!) choice to adopt the terminating-model rather than the restartable one for exception handling, in a few cases of specific interest to numeric computation in a symbolic setting. Most callbacks are module-global, with one specific exception. When any gmpy function or method is trying to convert arguments to gmpy objects (mpz, mpq, mpf), and a conversion fails, all argument objects are examined, looking for a method called '__gmpy__' in any of them. If one is found, then, rather than raising an error to indicate the conversion failure, that method is called as a 'localized callback' as above. This lets other, non-gmpy objects participate in gmpy computations (if they're willing to handle all cases involving them!): Python does much of this via __coerce__ etc, and this localized-callback facility does the rest for named module-functions and methods, where normal coercion would not apply. --- NEW FILE: index.html --- <HTML> <HEAD> <TITLE>Welcome to General Multiprecision PYthon </TITLE> <LINK rel="stylesheet" href="http://sourceforge.net/sourceforge.css" type="text/css"> <STYLE> body { margin-left: 30; margin-right: 30; } </STYLE> </HEAD> <BODY> <FONT SIZE=-1> Last updated on: 2001, Jan 25; for GMPY release: 0.9 pre-alpha <A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=13335&type=1" width="88" height="31" border="0" alt="Go to main SourceForge page"></A> <br> </FONT> <H1>GMPY Project goals and strategies</H1> The General Multiprecision PYthon project (GMPY) focuses on Python-usable modules providing multiprecision arithmetic functionality to Python programmers. The project mission includes both C and C++ Python-modules (for speed) and pure Python modules (for flexibility and convenience); it potentially includes integral, rational and floating-point arithmetic in any base. Only cross-platform functionality is of interest, at least for now. <P> As there are many good existing free C and C++ libraries that address these issues, it is expected that most of the work of the GMPY project will involve wrapping, and exposing to Python, exactly these existing libraries (possibly with additional "convenience" wrappers written in Python itself). For starters, we've focused on the popular (and excellent) GNU Multiple Precision library, <A HREF="http://www.swox.com/gmp/">GMP</A>, exposing its functionality through module <b>gmpy</b>. <H1>The GMPY Module</H1> <P> Existing Python modules expose a subset of the integral-MP (MPZ) functionality of earlier releases of the GMP library. The first GMPY goal is to develop this module into a complete exposure of MPZ, MPF (floating-point), and MPQ (rational) functionality of current GMP (release 3.1), that will fully support current Python (release 2.0) and its handy 'distutils' (and also support a "C API" allowing some level of interoperation with other C-written extension modules for Python). <p> <b>Note</b>: the module's ability to be used as a "drop-in replacement" for Python's own implementation of <i>long</i>s, to rebuild Python from sources in a version using GMP, was a characteristic of the gmp-module we started from, but is <b>not</b> a target of the gmpy project, and we have no plans to support it. <P> This first module is called <b>gmpy</b>, just like the whole project. <P> The extended MP floating-point facilities of <A HREF="http://www.loria.fr/projets/mpfr/">MPFR</A> will later also be considered for inclusion in gmpy (either within the same module, or as a further, separate add-on module). <H2>Mutability... but <u>not</u> for now</H2> Early tests have shown that supporting Python 2.0's "in-place operation" functionality (by making MPZ, MPF and MPQ Python objects <b>mutable</b>) could offer a substantial performance boost. <p> Despite this, widespread feeling among Python cognoscenti appears to be against exposing such "mutable numbers". As a consequence, our current aim is for a first release of GMPY without mutability, to be followed at some later time by one which will also fully support in-place-mutable versions of number objects (as well as the default immutable ones), but only when explicitly and deliberately requested by a user (who can then be presumed to know what he or she is doing). Meanwhile, caching strategies are used to ameliorate performance issues, and appear to be reasonably worthwhile (so far, only MPZ and MPQ objects are subject to this caching). <p> We've tended to solve other debatable design issues in a similar vein, i.e., by trying to work "like Python's built-in numbers" when there was a choice and two or more alternatives made sense. <H1>Project Status and near-future plans</H1> The gmpy module's early, pre-alpha releases (latest current release as of 2001/01/25: 0.9) are already available for download in both source and Windows-binary form. They expose all of the mpz, mpq and mpf functionality available in GMP 3.1, and most of the random-number generation functionality (there are no current plans to extend gmpy to expose other such functionality, although the currently experimental way that it is architected is subject to likely future changes). <p> On most platforms, you will need to separately procure and install the GMP library itself to be able to build and use GMPY (note that 3.1.1 or better is needed; take care: some Linux releases come bundled with <strong>older</strong> GMP versions, such as GMP 2, and you may have to uninstall these and then install the latest GMP version!). <p> The exception to this need is under (32-bit) Windows, where binary-accompanied releases are the norm, and builds of GMP usable with MS VC++ 6 (the main C compiler used for Python on this platform) are traditionally hard to come by. <p> We started the GMPY project using a VC++ port of GMP.LIB "just found on the net", but have currently switched to the port by Jorgen Lundman found at <a href="ftp://ftp.whiterose.net/pub/lundman/"> ftp://ftp.whiterose.net/pub/lundman/</a> (bravo Lundy!). Windows users do not need to download from Jorgen's site: a separate 'binary library' package, including Lundy's ports of GMP.LIB and GMP.H, is made available on the gmpy project's ftp-space for Windows/VC++6 users that do want to re-build the gmpy module from sources; and also, another separate 'binary module' package is supplied, containing only the pre-built GMPY.PYD, for those who do <b>not</b> want to re-build from sources. <p> <b>Do</b> note, however, that <b>all</b> gmpy users should download the gmpy source-package as well, as currently that is the one including <b>gmpy</b> documentation and unit-tests! <H2>Currently-open issues</h2> <p> A still-weakish point is with the output-formatting of mpf numbers; sometimes, this formatting ends up providing a few more digits than a given number's accuracy would actually warrant (a few noise digits after a long string of trailing '0' or '9' digits), particularly when the mpf number is built from a Python float -- the accuracy situation is quite a bit better when the mpf number is built from a <b>string</b>. <p> Because of this, since release 0.6, gmpy introduced an optional 'floating-conversion format string' module-level setting: if present, float->mpf conversion goes through an intermediate formatted string (by default, it still proceeds directly, at least for now); this does ameliorate things a bit, as does the better tracking done (since 0.6, with further enhancements in 0.7) of the 'requested' precision for an mpf (as opposed to the precision the underlying GMP actually 'assigns' to it); but the issue cannot yet be considered fully solved, and may well still need some design changes in the output formatting functionality. <p> Unit tests are not considered a weak point any more; the almost-1000 unit-tests now being run provide a decent cover of 92+% SLOC for gmpy.c, up from 72% in 0.7. The non-covered SLOCs (about 170 of gmpy.c's current 2370) are mostly disaster-tests to handle out-of-memory situations, and code providing optional debugging output (for debugging the gmpy module -- see the set_debug facility), with a smattering of 'defensive programming' cases (to handle situations that 'should never happen, but'...) and some cases of the new experimental 'callbacks' facility (mostly provided for the specific use of PySymbolic, and intended to be tested by that package). We'll have to do better, eventually, but, for now, this can be considered OK for an alpha-release. <p> In the attempt to make gmpy as useful as can be for both stand-alone use, and also in the context of PySymbolic, a tad too many design decisions have been delayed/postponed by introducing module-level flags, letting us 'have it both ways' in the current pre-alpha gmpy; this has produced a somewhat unwieldy mix of module-level flag-setting and call-back functions. This whole area's architecture will neet to be revisited, including other such design-decisions yet. <H2>Near-future plans</h2> The first alpha release, 1.0, is not deemed to be very far at this time. It will only differ in degree, not in kind, from the current pre-alphas. <p> Main changes foreseen will include: re-architecting the module-level setting functions; more elegantly formatted documentation; more timing-measurement scripts and usage-examples. Some of the currently experimental 'callbacks' will also be removed, as having been proven unnecessary. <p> The current plans forecast all of this will be completed on, or before, March 1, 2000 (give or take about 10 days). <p> <A HREF="http://sourceforge.net/projects/gmpy/">Project Summary, downloads, &tc</A> <A href="http://sourceforge.net/projects/gmpy/"> <IMG src="http://sourceforge.net/sflogo.php?group_id=13335&type=1" width="88" height="31" border="0" alt="Project Summary Page"></A> </BODY> </HTML> |
From: Gustavo N. <nie...@us...> - 2001-12-11 10:30:03
|
Update of /cvsroot/gmpy/gmpy In directory usw-pr-cvs1:/tmp/cvs-serv30377 Added Files: setes.py setup.py Log Message: Added files to repository. --- NEW FILE: setes.py --- import sys from distutils.core import setup, Extension if sys.version.find('MSC')==-1: gmpy_ext = Extension('pysymbolicext', sources=['pysymbolicext.c'], libraries=['gmp']) else: gmpy_ext = Extension('pysymbolicext', sources=['pysymbolicext.c'], libraries=['gmp'],include_dirs=['.']) setup (name = "pysymbolicext", version = "0.2", description = "GMP-3 to Python-2 interface", maintainer = "Alex Martelli", maintainer_email = "al...@ya...", url = "http://gmpy.sourceforge.net/", ext_modules = [ gmpy_ext ] ) --- NEW FILE: setup.py --- import sys from distutils.core import setup, Extension if sys.version.find('MSC')==-1: gmpy_ext = Extension('gmpy', sources=['src/gmpy.c'], libraries=['gmp']) else: gmpy_ext = Extension('gmpy', sources=['src/gmpy.c'], include_dirs=['./src']) setup (name = "gmpy", version = "0.9", description = "GMP-3 to Python-2 interface", maintainer = "Alex Martelli", maintainer_email = "al...@ya...", url = "http://gmpy.sourceforge.net/", ext_modules = [ gmpy_ext ] ) |
From: Gustavo N. <nie...@us...> - 2001-12-07 19:40:58
|
Update of /cvsroot/gmpy/gmpy/doc In directory usw-pr-cvs1:/tmp/cvs-serv29191/doc Log Message: Directory /cvsroot/gmpy/gmpy/doc added to the repository |