pax_global_header00006660000000000000000000000064140664661310014521gustar00rootroot0000000000000052 comment=894b17b9e7bd9d9f484680c89889d4abbda31e5c pynac-pynac-0.7.29/000077500000000000000000000000001406646613100140425ustar00rootroot00000000000000pynac-pynac-0.7.29/.github/000077500000000000000000000000001406646613100154025ustar00rootroot00000000000000pynac-pynac-0.7.29/.github/workflows/000077500000000000000000000000001406646613100174375ustar00rootroot00000000000000pynac-pynac-0.7.29/.github/workflows/ci-sage.yml000066400000000000000000000402071406646613100214750ustar00rootroot00000000000000name: Run Sage CI for Linux/Cygwin/macOS ## This GitHub Actions workflow provides: ## ## - portability testing, by building and testing this project on many platforms ## (Linux variants and Cygwin), each with two configurations (installed packages), ## ## - continuous integration, by building and testing other software ## that depends on this project. ## ## It runs on every push to the GitHub repository. ## ## The testing can be monitored in the "Actions" tab of the GitHub repository. ## ## After all jobs have finished (or are canceled) and a short delay, ## tar files of all logs are made available as "build artifacts". ## ## This GitHub Actions workflow uses the portability testing framework ## of SageMath (https://www.sagemath.org/). For more information, see ## https://doc.sagemath.org/html/en/developer/portability_testing.html ## The workflow consists of two jobs: ## ## - First, it builds a source distribution of the project ## and generates a script "update-pkgs.sh". It uploads them ## as a build artifact named upstream. ## ## - Second, it checks out a copy of the SageMath source tree. ## It downloads the upstream artifact and replaces the project's ## package in the SageMath distribution by the newly packaged one ## from the upstream artifact, by running the script "update-pkgs.sh". ## Then it builds a small portion of the Sage distribution. ## ## Many copies of the second step are run in parallel for each of the tested ## systems/configurations. on: [push, pull_request, workflow_dispatch] ## Uncomment this (and comment the above) to run only on pushes to a tag, ## not on all pushes to a branch. ## ## on: ## pull_request: ## types: [opened, synchronize] ## push: ## tags: ## - '*' ## workflow_dispatch: ## # Allow to run manually env: # Ubuntu packages to install so that the project's "make dist" can succeed DIST_PREREQ: libtool libflint-dev libsingular4-dev # Name of this project in the Sage distribution SPKG: pynac # Sage distribution packages to build TARGETS_PRE: build/make/Makefile TARGETS: SAGE_CHECK=no SAGE_CHECK_PACKAGES=pynac pynac TARGETS_OPTIONAL: build/make/Makefile # Standard setting: Test the current beta release of Sage: SAGE_REPO: sagemath/sage SAGE_REF: develop # Temporarily test with the branch from a sage ticket with build script fixes # (this is a no-op after that ticket is merged) SAGE_TRAC_GIT: https://github.com/sagemath/sagetrac-mirror.git SAGE_TICKET: REMOVE_PATCHES: "*" jobs: dist: runs-on: ubuntu-latest steps: - name: Check out ${{ env.SPKG }} uses: actions/checkout@v2 with: path: build/pkgs/${{ env.SPKG }}/src - name: Install prerequisites run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install $DIST_PREREQ - name: Run make dist, prepare upstream artifact run: | (cd build/pkgs/${{ env.SPKG }}/src && autoreconf -fi && ./configure && make dist) \ && mkdir -p upstream && cp build/pkgs/${{ env.SPKG }}/src/*.tar.gz upstream/${{ env.SPKG }}-git.tar.gz \ && echo "sage-package create ${{ env.SPKG }} --version git --tarball ${{ env.SPKG }}-git.tar.gz --type=standard" > upstream/update-pkgs.sh \ && if [ -n "${{ env.REMOVE_PATCHES }}" ]; then echo "(cd ../build/pkgs/${{ env.SPKG }}/patches && rm -f ${{ env.REMOVE_PATCHES }}; :)" >> upstream/update-pkgs.sh; fi \ && ls -l upstream/ - uses: actions/upload-artifact@v2 with: path: upstream name: upstream cygwin: env: STAGE: i-a LOCAL_ARTIFACT_NAME: sage-local-commit-${{ github.sha }}-cygwin-${{ matrix.pkgs }} LOGS_ARTIFACT_NAME: logs-commit-${{ github.sha }}-cygwin-${{ matrix.pkgs }} MAKE: make -j8 SAGE_NUM_THREADS: 3 SAGE_CHECK: yes SAGE_CHECK_PACKAGES: "!cython,!r,!python3,!python2,!nose,!pathpy,!gap,!cysignals,!linbox,!git,!ppl" CYGWIN: winsymlinks:native CONFIGURE_ARGS: --enable-experimental-packages --enable-download-from-upstream-url SAGE_FAT_BINARY: yes SAGE_LOCAL: /opt/sage-pynac-${{ github.sha }} runs-on: windows-latest needs: [dist] strategy: fail-fast: false matrix: pkgs: [minimal, standard] steps: - run: | git config --global core.autocrlf false git config --global core.symlinks true - name: install cygwin with choco shell: bash {0} run: | choco --version choco install git python3 --source cygwin - name: Check out SageMath uses: actions/checkout@v2 with: repository: ${{ env.SAGE_REPO }} ref: ${{ env.SAGE_REF }} fetch-depth: 2000 if: env.SAGE_REPO != '' - name: Check out git-trac-command uses: actions/checkout@v2 with: repository: sagemath/git-trac-command path: git-trac-command if: env.SAGE_TRAC_GIT != '' - name: Check out SageMath from trac.sagemath.org shell: bash {0} # Random sleep and retry to limit the load on trac.sagemath.org run: | git config --global user.email "ci-sage@example.com" git config --global user.name "ci-sage workflow" if [ ! -d .git ]; then git init; fi; git remote add trac ${{ env.SAGE_TRAC_GIT }} && x=1 && while [ $x -le 5 ]; do x=$(( $x + 1 )); sleep $(( $RANDOM % 60 + 1 )); if git-trac-command/git-trac fetch $SAGE_TICKET; then git merge FETCH_HEAD || echo "(ignored)"; exit 0; fi; sleep 40; done; exit 1 if: env.SAGE_TRAC_GIT != '' - uses: actions/download-artifact@v2 with: path: upstream name: upstream - name: install minimal prerequisites with choco shell: bash {0} run: | choco --version PACKAGES="python38 python38-pip" choco install $PACKAGES --source cygwin - name: Update Sage packages from upstream artifact run: | C:\\tools\\cygwin\\bin\\bash -l -c 'cd $(cygpath -u "$GITHUB_WORKSPACE") && ls -l upstream/ && export PATH="$(pwd)/build/bin:$PATH:/usr/local/bin:/usr/bin" && (cd upstream && bash -x update-pkgs.sh) && git diff' - name: tox run: | C:\\tools\\cygwin\\bin\\bash -l -x -c 'python3.8 -m pip install tox' C:\\tools\\cygwin\\bin\\bash -l -x -c 'cd $(cygpath -u "$GITHUB_WORKSPACE") && PREFIX="${{ env.SAGE_LOCAL }}" tox -e local-cygwin-choco-${{ matrix.pkgs }} -- $TARGETS' - name: Prepare logs artifact shell: bash run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME"; for a in local/var/tmp/sage/build/*; do if [ -d $a ]; then tar -c --remove-files -f "artifacts/$LOGS_ARTIFACT_NAME/$(basename $a).tar" $a || tar -c --ignore-failed-read -f "artifacts/$LOGS_ARTIFACT_NAME/$(basename $a)-save.tar" $a ; fi; done; cp -r logs/* "artifacts/$LOGS_ARTIFACT_NAME" if: always() - uses: actions/upload-artifact@v2 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} if: always() - name: Print out logs for immediate inspection # The markup in the output is a GitHub Actions logging command # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions shell: bash run: | find "artifacts/$LOGS_ARTIFACT_NAME" -type f -name "*.log" -exec sh -c 'if tail -20 "{}" 2>/dev/null | grep "^Error" >/dev/null; then echo :":"error file={}:":" ==== LOG FILE {} CONTAINS AN ERROR ====; cat {} ; fi' \; if: always() - name: Prepare sage-local artifact # We specifically use the cygwin tar so that symlinks are saved/restored correctly on Windows. # We remove the $SAGE_LOCAL/lib64 link, which will be recreated by the next stage. run: | C:\\tools\\cygwin\\bin\\bash -l -c 'cd $(cygpath -u "$GITHUB_WORKSPACE") && rm -f "${{ env.SAGE_LOCAL }}"/lib64; tar -cf /tmp/sage-local-${{ env.STAGE }}.tar --remove-files "${{ env.SAGE_LOCAL }}"' if: always() - uses: actions/upload-artifact@v2 # upload-artifact@v2 does not support whitespace in file names. # so we tar up the directory ourselves with: path: C:\\tools\\cygwin\\tmp\\sage-local-${{ env.STAGE }}.tar name: ${{ env.LOCAL_ARTIFACT_NAME }} if: always() docker: runs-on: ubuntu-latest needs: [dist] strategy: fail-fast: false max-parallel: 32 matrix: tox_system_factor: [ubuntu-trusty, ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-groovy, ubuntu-hirsute, debian-jessie, debian-stretch, debian-buster, debian-bullseye, debian-sid, linuxmint-17, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, centos-7, centos-8, gentoo, archlinux-latest, opensuse-15, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-nvidia-cuda, centos-nvidia-cuda, ubuntu-focal-nvidia-cuda, ubuntu-bionic-nvidia-cuda, ubuntu-xenial-nvidia-cuda, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386, raspbian-buster-armhf] tox_packages_factor: [minimal, standard] env: TOX_ENV: docker-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} LOGS_ARTIFACT_NAME: logs-commit-${{ github.sha }}-tox-docker-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} DOCKER_TARGETS: configured with-targets with-targets-optional steps: - name: Check out SageMath uses: actions/checkout@v2 with: repository: ${{ env.SAGE_REPO }} ref: ${{ env.SAGE_REF }} fetch-depth: 2000 if: env.SAGE_REPO != '' - name: Check out git-trac-command uses: actions/checkout@v2 with: repository: sagemath/git-trac-command path: git-trac-command if: env.SAGE_TRAC_GIT != '' - name: Check out SageMath from trac.sagemath.org shell: bash {0} run: | git config --global user.email "ci-sage@example.com" git config --global user.name "ci-sage workflow" if [ ! -d .git ]; then git init; fi; git remote add trac ${{ env.SAGE_TRAC_GIT }} && x=1 && while [ $x -le 5 ]; do x=$(( $x + 1 )); sleep $(( $RANDOM % 60 + 1 )); if git-trac-command/git-trac fetch $SAGE_TICKET; then git merge FETCH_HEAD || echo "(ignored)"; exit 0; fi; sleep 40; done; exit 1 if: env.SAGE_TRAC_GIT != '' - uses: actions/download-artifact@v2 with: path: upstream name: upstream - name: Install test prerequisites run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install tox python3-setuptools - name: Update Sage packages from upstream artifact run: | (export PATH=$(pwd)/build/bin:$PATH; (cd upstream && bash -x update-pkgs.sh) && sed -i.bak '/upstream/d' .dockerignore && echo "/:toolchain:/i ADD upstream upstream" | sed -i.bak -f - build/bin/write-dockerfile.sh && git diff) - name: Configure and build Sage distribution within a Docker container run: | set -o pipefail; EXTRA_DOCKER_BUILD_ARGS="--build-arg USE_MAKEFLAGS=\"-k V=0 SAGE_NUM_THREADS=3\"" tox -e $TOX_ENV -- $TARGETS 2>&1 | sed "/^configure: notice:/s|^|::warning file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;/^configure: warning:/s|^|::warning file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;/^configure: error:/s|^|::error file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;" - name: Copy logs from the Docker image or build container run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME" cp -r .tox/$TOX_ENV/Dockerfile .tox/$TOX_ENV/log "artifacts/$LOGS_ARTIFACT_NAME" if [ -f .tox/$TOX_ENV/Dockertags ]; then CONTAINERS=$(docker create $(tail -1 .tox/$TOX_ENV/Dockertags) /bin/bash || true); fi if [ -n "$CONTAINERS" ]; then for CONTAINER in $CONTAINERS; do for ARTIFACT in /sage/logs; do docker cp $CONTAINER:$ARTIFACT artifacts/$LOGS_ARTIFACT_NAME && HAVE_LOG=1; done; if [ -n "$HAVE_LOG" ]; then break; fi; done; fi if: always() - uses: actions/upload-artifact@v2 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} if: always() - name: Print out logs for immediate inspection # and markup the output with GitHub Actions logging commands run: | .github/workflows/scan-logs.sh "artifacts/$LOGS_ARTIFACT_NAME" if: always() - name: Push Docker images run: | if [ -f .tox/$TOX_ENV/Dockertags ]; then TOKEN="${{ secrets.DOCKER_PKG_GITHUB_TOKEN }}" if [ -z "$TOKEN" ]; then TOKEN="${{ secrets.GITHUB_TOKEN }}" fi echo "$TOKEN" | docker login docker.pkg.github.com -u ${{ github.actor }} --password-stdin for a in $(cat .tox/$TOX_ENV/Dockertags); do FULL_TAG=docker.pkg.github.com/$(echo ${{ github.repository }}|tr 'A-Z' 'a-z')/$a docker tag $a $FULL_TAG echo Pushing $FULL_TAG docker push $FULL_TAG done || echo "(Ignoring errors)" fi if: always() macos: runs-on: macos-latest strategy: fail-fast: false max-parallel: 4 matrix: os: [ macos-10.15, macos-11.0 ] tox_system_factor: [homebrew-macos, conda-forge-macos] tox_packages_factor: [minimal, standard] xcode_version_factor: [11.7, default] needs: [dist] env: TOX_ENV: local-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} LOGS_ARTIFACT_NAME: logs-commit-${{ github.sha }}-tox-local-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }}-${{ matrix.os }}-xcode_${{ matrix.xcode_version_factor }} DOCKER_TARGETS: configured with-targets with-targets-optional steps: - name: Select Xcode version run: | if [ ${{ matrix.xcode_version_factor }} != default ]; then sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode_version_factor }}.app; fi - name: Check out SageMath uses: actions/checkout@v2 with: repository: ${{ env.SAGE_REPO }} ref: ${{ env.SAGE_REF }} fetch-depth: 2000 if: env.SAGE_REPO != '' - name: Check out git-trac-command uses: actions/checkout@v2 with: repository: sagemath/git-trac-command path: git-trac-command if: env.SAGE_TRAC_GIT != '' - name: Check out SageMath from trac.sagemath.org shell: bash {0} run: | git config --global user.email "ci-sage@example.com" git config --global user.name "ci-sage workflow" if [ ! -d .git ]; then git init; fi; git remote add trac ${{ env.SAGE_TRAC_GIT }} && x=1 && while [ $x -le 5 ]; do x=$(( $x + 1 )); sleep $(( $RANDOM % 60 + 1 )); if git-trac-command/git-trac fetch $SAGE_TICKET; then git merge FETCH_HEAD || echo "(ignored)"; exit 0; fi; sleep 40; done; exit 1 if: env.SAGE_TRAC_GIT != '' - uses: actions/download-artifact@v2 with: path: upstream name: upstream - name: Update Sage packages from upstream artifact run: | (export PATH=$(pwd)/build/bin:$PATH; (cd upstream && bash -x update-pkgs.sh) && git diff) - name: Install test prerequisites run: | brew install tox - name: Build and test with tox # We use a high parallelization on purpose in order to catch possible parallelization bugs in the build scripts. # For doctesting, we use a lower parallelization to avoid timeouts. run: | MAKE="make -j12" tox -e $TOX_ENV -- SAGE_NUM_THREADS=4 $TARGETS - name: Prepare logs artifact run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME"; cp -r .tox/*/log "artifacts/$LOGS_ARTIFACT_NAME" if: always() - uses: actions/upload-artifact@v1 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} if: always() - name: Print out logs for immediate inspection # and markup the output with GitHub Actions logging commands run: | .github/workflows/scan-logs.sh "artifacts/$LOGS_ARTIFACT_NAME" if: always() pynac-pynac-0.7.29/.gitignore000066400000000000000000000007231406646613100160340ustar00rootroot00000000000000Makefile Makefile.in aclocal.m4 autom4te.cache/ config.guess config.h pynac-config.h config.h.in config.log config.status config.sub configure depcomp ginac/.deps/ ginac/.libs/ ginac/Makefile ginac/Makefile.in ginac/*.la ginac/*.lo ginac/*.o ginac/*.orig ginac/*.rej ginac/*.swp ginac/pynac-config.h ginac/version.h install-sh libtool ltmain.sh m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 missing pynac*tar.bz2 pynac*tar.gz stamp-h1 pynac-pynac-0.7.29/.hgignore000066400000000000000000000002431406646613100156440ustar00rootroot00000000000000%*.la %*.lo %*.o %*~ %*.libs/ %*.rej .*sw[p-z]$ ginac/tags Makefile config.guess config.sub stamp-h1 version.h pynac.pc pynac.spec m4 install-sh ltmain.sh missing pynac-pynac-0.7.29/AUTHORS000066400000000000000000000025071406646613100151160ustar00rootroot00000000000000The Pynac Group --------------- see also https://github.com/pynac/pynac/graphs/contributors François Bissey Robert Bradshaw Volker Braun Erik Bray Burcin Erocal Jean-Pierre Flori Benjamin Hackl Carlos R. Mafra Paul Masson R. Andrew Ohana Clément Pernet William Stein Ralf Stephan Aaditya Thakkar The GiNaC Group --------------- Christian Bauer Chris Dams Alexander Frink Vladimir V. Kisil Richard Kreckel Alexei Sheplyakov Jens Vollinga Authors of optional.hpp ----------------------- In this package the file optional.hpp is distributed under the MIT license. Author: Martin Moene, see https://github.com/martinmoene/optional-lite Contributors of patches ----------------------- Roberto Bagnara, Do Hoang Son, Markus Nullmeier, Pearu Peterson, Benedikt Pluemper, Ben Sapp, Stefan Weinzierl. (Please send email if you think you were forgotten.) Contacting the authors ---------------------- If you have found a bug, have a patch or a question or would like to make a suggestion please visit https://github.com/pynac/pynac/issues and open a new issue. This avoids both potential duplication of work and delays caused by possible vacations. pynac-pynac-0.7.29/CONTRIBUTING.md000066400000000000000000000115771406646613100163060ustar00rootroot00000000000000Pynac is a C++ library for symbolic manipulation based on GiNaC. It can use arbitrary Python objects for numeric types. Since Pynac is closely tied to Sage, setting up a development environment and finding your way around initially can be troublesome. This is a short tutorial to provide help with the first steps. GiNaC (Pynac's ancestor) has great documentation. It's a good idea to read the [tutorial](http://www.ginac.de/tutorial/) to get familiar with the library. The [reference manual](http://www.ginac.de/reference/) for GiNaC can also be useful to find your way around. (This is a copy of https://github.com/pynac/pynac/wiki/Setting-up-a-development-environment which might be newer) ### Setting up a development environment One way to set up a development pipeline is to follow these steps: 0. have Sage built from git source. **In the following `SAGE_ROOT` means the full path to the directory where you installed Sage.** 1. if the current branch from https://github.com/pynac/sage is newer than Sage develop then fetch and build it 2. `cd` into `SAGE_ROOT` 3. clone the pynac repository: `git clone git@github.com:pynac/pynac.git` or extract the source from the `upstream` subdirectory with `tar xvfj upstream/pynac-...tar.bz2` 4. `cd` into the created directory 5. if you cloned the repo this is the time to create files needed for build (they are included in the tarball). This needs `autoconf`, `automake`, `m4`, `libtoolize`, and `autoreconf` installed on your machine. Do: ``` user@host: aclocal user@host: autoconf user@host: autoreconf --install user@host: automake ``` Now type ``` export CFLAGS=-I$SAGE_ROOT/local/include ./configure --includedir=$SAGE_ROOT/local/include --libdir=$SAGE_ROOT/local/lib` PKG_CONFIG_PATH=$SAGE_ROOT/local/lib/pkgconfig ``` and the development environment is set up (to compile Pynac outside Sage you need to give configure a hint where the headers of dependent packages are if you only have installed those packages via Sage, as opposed to a system installation of e.g. flint). After having changed Pynac to your liking you want to test it inside the newest Sage. 1. inside `SAGE_ROOT/pynac` say `make dist` 2. copy the resulting `bz2` tarball to `SAGE_ROOT/upstream` 3. `cd` to `SAGE_ROOT` and: ``` user@host: ./sage --package fix-checksum user@host: ./sage -p pynac user@host: make user@host: ./sage -tp -a ``` If no doctests fail you're ready to go! Instead of `make` which also builds the full documentation you might want to use `make start` if you are not interested in that. (Previously the install instructions went like this:) In order to start working on the source code go to your `SAGE_ROOT` and run `./sage -f -m spkg/standard/pynac-*.spkg`. This will install the latest version of Pynac that comes with Sage and leave the package files in the directory `spkg/build/pynac-`. You will find the Pynac sources in `spkg/build/pynac-/src`, most files you'll want to work on are in the subdirectory `ginac`. After you make changes to the Pynac files, in order to build your changes and install them so Sage will see them, get in a Sage shell with ``` ./sage -sh ``` Go to the Pynac source directory ``` cd spkg/build/pynac-*/src ``` and run ``` make install ``` (copy of https://github.com/pynac/pynac/wiki/Development-protocol) ### Respect the existing C++ style In particular: * 8-space expanded tabs (no TAB characters) * Code blocks: * The braces opening a **function block** should be on a new line. * The braces opening a **condition block** should be on the end of the line with the condition. The closing braces should be indented such that they are on the same column as the start of the condition statement. ### Pull requests and the release cycle * Pull requests must compile without warning to be accepted. * Make sure your master branch is up-to-date so that fixes from other developers are applied. * There is a branch at https://github.com/pynac/sage which contains modifications to SageMath's source code and/or documentation such that (ideally) the current development version of pynac passes all of SageMath's doctests. * If one of your PRs requires a change in SageMath's doctests, please add the diff from **the changes to SageMath** as a code comment to your PR, or consider opening a PR to the upgrade branch at https://github.com/pynac/sage itself. * Before submitting a PR to pynac you should test your changes at least against the doctests in `src/sage/symbolic`, `src/sage/functions`, `src/sage/calculus`, `src/sage/tests/`,and `src/doc/`. * The release maintainer will do a full test in the freezing phase. * In the freezing phase no PRs get accepted, and developers are required to fix remaining failing doctests. * After the freezing phase, a new version of pynac is released and the development phase for the next pynac version begins. * freezing is announced in https://groups.google.com/forum/?hl=en#!forum/pynac-devel so please subscribe. pynac-pynac-0.7.29/COPYING000066400000000000000000000433631406646613100151060ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pynac-pynac-0.7.29/ChangeLog000066400000000000000000000005601406646613100156150ustar00rootroot00000000000000This file is not yet operational. Eventually it should record all changes. Till then, you are advised to resort to our CVS server where all changes are logged. This is how to get anonymous read-only access: $ cvs -d :pserver:anoncvs@cvs.ginac.de:/home/cvs/GiNaC login enter the password `anoncvs' $ cvs -d :pserver:anoncvs@cvs.ginac.de:/home/cvs/GiNaC -z 9 co GiNaC pynac-pynac-0.7.29/INSTALL000066400000000000000000000366141406646613100151050ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. pynac-pynac-0.7.29/Makefile.am000066400000000000000000000010631406646613100160760ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in SUBDIRS = ginac DIST_SUBDIRS = ginac # pkg-config metadata pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = pynac.pc $(pkgconfig_DATA): config.status # All the rest of the distributed files EXTRA_DIST = pynac.pc pynac.spec CONTRIBUTING.md PACKAGING.md # Rule to build tar-bzipped distribution package $(PACKAGE)-$(VERSION).tar.gz: dist # Rule to build RPM distribution package .PHONY: rpm rpm: $(PACKAGE)-$(VERSION).tar.gz rpmbuild -ta --clean $(PACKAGE)-$(VERSION).tar.gz ACLOCAL_AMFLAGS=-I m4 pynac-pynac-0.7.29/NEWS000066400000000000000000000774041406646613100145550ustar00rootroot00000000000000This file records noteworthy changes. (for Pynac-specific changes please see https://github.com/pynac/pynac/wiki/Changelog) 1.4.3 (04 April 2008) * Fixed bug in numerical evaluation of multiple polylogarithms and alternating multiple zeta values introduced in version 1.4.2. * Nielsen polylog now invalidates its lookup tables in case the precision (Digits) has been changed. * Added new checks for recent bugs in the numerical evaluation of Li and zeta. 1.4.2 (03 April 2008) * Fixed VPATH building of documentation. * Fixed bug in numerical evaluation of multiple polylogarithms for arguments equal to certain roots of unity (thanks to Jianqiang Zhao). * Fixed check for memory leakage in parser. * Made internal function coerce() standard compliant. * Improved lsolve() of systems containing non-numeric coefficients. * Improved automatic test programs. Now they work on MinGW and Cygwin as well. 1.4.1 (21 November 2007) * Fixed memory leak in ginac_yylex(). * Fixed memory leaks in mul::eval() and power::eval(). * Fixed macro checking for version of libreadline (Mac OS X). * Fixed broken preprocessor instruction in excompiler.cpp. * Fixed broken module loading in excompiler.cpp. * info(info_flags::has_indices) now works for sums and products. * Improved mul::expand(). * Improved CLN output. 1.4.0 (31 August 2007) * New tinfo mechanism. * Removed rtt from class symbol. * Faster archiving by adding a map from strings to indices in the atoms vector. * Improved unarchiving: algorithms order N instead of order N^2. * Added compile function, excompiler class. * Added exset type. * Added step function to GiNaCs built-in functions. * Added is_polynomial() method. * Added real_part() and imag_part() methods. * Added matrix::is_zero_matrix() method. * Added evalm() method to pseries class. * Improved dummy index renaming. * Many improvements for class clifford. * New flag for positive symbols/numbers, added possymbol class. * Added programming examples in doc/examples 1.3.9 (21 November 2007) Backporting bug-fix release from version 1.4.1. 1.3.8 (28 August 2007) * Drop support of ginac-config and ginac.m4. Please use pkg-config instead. * atan2(y,x) branch cut correction. * Fixed bug in series expansion. * Additional transformations for mul and power. * Clifford units now honor representation labels. * Correct csrc output for idx and fderivative. * Improved handling of convergence transformationis for Li/G. * Fix compilation issues with prereleases of GCC 4.3. * info_flags::expanded added. * input_parser also accepts pow(). * texinfo.tex removed from package. 1.3.7 (05 February 2007) * Fixed bug in expansion of power. * Fixed bugs in functions S() (infinite loop), H() and zeta() (wrong results). * Rebuilt bison related files with bison version 2.3 (fixes parse error bugs). * Improved power::eval(). * Improved libreadline detection. 1.3.6 (13 December 2006) * Better worst case behavior in heuristic gcd. * Improved collecting for sparse multivariate polynomials. * Improved collect_common_factors. * Fixed bug in numerical evaluation of multiple polylogs. * Fixed numerical integration of complex functions. * Fixed bug in tensor::replace_contr_index(). 1.3.5 (17 August 2006) * Re-built bison related files that caused bugs with gcc 4. * Fixed bugs in fderivative::match_same_type(), expairseq::match(), expand_dummy_sum(), and expairseq::map(). * Fixed template specialization for class container to be gcc 4.2 compliant. * Output in csrc mode is now -x instead of -1.0*x. * Fixed tutorial and reference generation in html/pdf/ps format. * Modified autotool configuration to allow for compilation on MinGW. * Debian packaging files updated. 1.3.4 (12 April 2006) * More general index dimensions are now possible. * Improved algebraic substitutions. * Fixed wrong matching in .has(). * Fixed bug in differentiation of a power. * collect_common_factors also works with negative powers of common factors now. * Code clean-up and preparations for upcoming cln 1.2. 1.3.3 (24 October 2005) * Fixed bug occurring in algebraic substitutions with expressions involving indices. * Fixed bug that selected the wrong algorithm for determinants of purely numeric matrices with at least one floating point element. * Fixed bug in function H that caused an infinite recursion for arguments around +-I. * Fixed const-correctness in printing handler for GCC 4.0.2. * Made lookup in adaptivesimpson precision-aware. * Added series expansion for functions (classical) Li and S around x==0. * Added fsolve() numerical univariate real-valued function solver. * Added functions sub_matrix() and reduced_matrix(). * Small cleanups. Less warnings with latest GCC. 1.3.2 (10 July 2005) * GCD avoids to produce expanded expressions. * Fixed bug in expanding expressions containing dummy indices. * Fixed static initialization order bug. * collect_common_factors now works with powers. * Modernized configuration scripts. 1.3.1 (04 May 2005) * integral() and eval_integ() can be used from ginsh. * Integrals can be series-expanded. * Fixed a library initialization problem. * GiNaC compiles from tarball even if lex/flex is missing. * Fixed bugs in canonicalize_clifford(), clifford_prime() and clifford_to_lst(). * clifford_moebius_map(), remove_dirac_ONE() and LaTeX output of Clifford objects now care about representation labels. * Fixed bug in gcd. * Better output for slashed expressions 1.3.0 (19 October 2004) * The Clifford classes have been generalized to allow working with Clifford algebras generated by arbitrary symmetric tensors or matrices. Also, a lot of new functions for Clifford algebras have been added, including automorphisms and Moebius transformations. [V. Kisil] * Added some basic symbolic and numeric integration facilities. [C. Dams] * The multiple polylogarithm Li() now evaluates numerically for arbitrary arguments. * New functions G(a,y) and G(a,s,y) added (another notation for multiple polylogarithms). 1.2.4 (12 October 2004) * Added ex::unitcontprim() to compute the unit, content, and primitive parts of a polynomial in one go. * binomial(n, k) evaluates for non-integer arguments n. * Li(2,x) now evaluates for +-I. * Optimized Li(2,x). * Fixed bug in Li(n,x) (if Li(2,x) was calculated with high precision the enlargement of the look-up table caused a segmentation fault). * Fixed another bug in the series expansion of powers, and a bug in power::info(). 1.2.3 (13 August 2004) * Added variants of dirac_trace() and color_trace() that take the trace over more than one representation label by specifying a set or list of labels. * diracgamma::contract_with() uses Chisholm identities in 4 dimensions to produce more compact results. * Fixed a bug in the series expansion of powers. * The --enable-html-doc and --enable-ps-doc configure options are gone. Documentation in HTML, DVI, PostScript, and PDF formats is now built with "make html", "make dvi", "make ps", and "make pdf", respectively. The only documentation that gets built by default are the tutorial in .info format and the manpages. 1.2.2 (3 August 2004) * Added const_preorder_iterator and const_postorder_iterator classes (and associated methods ex::pre/postorder_begin/end()) providing tree traversal with iterators. * Fixed the LaTeX output of the varidx class. * Fixed bugs in series expansion and complex conjugation. * (p.i*p.i).get_free_indices() returns the correct result () instead of (.i). * Symbolic functions without any eval(), evalf() etc. functions now work properly. * integer_content(), content(), and primpart() now also work for polynomials with rational coefficients (calculating the LCM of coefficients' denominators). * Added method matrix::rank(). * Added function resultant(). * Added integer_content() function to ginsh. 1.2.1 (23 April 2004) * Fixed infinite recursion in atan2_evalf() and improved atan2_eval(). * Added automatic evaluations for trigonometric functions with negative arguments (e.g. sin(-2) -> -sin(2)). * Fixed a static initialization order goof-up. * Fixed various bugs in series expansion. 1.2.0 (19 March 2004) * Added a structure template class for the easy creation of user-defined algebraic classes. * Added support for (acyclic) visitors, to allow cleaner implementations of algebraic algorithms. * Added a const_iterator class that can be used instead of op()/nops(). * Completely revamped the implementation of expression output. It is now possible to add new output formats, to change the behavior of predefined formats at run-time, and to have different output styles for algebraic functions. * Symbols can be made non-commutative. * Added a method ex::conjugate() and a function conjugate() for complex conjugation. Symbols can be declared as real or complex-valued. * Improved the speed of subs(), normal(), to_rational() and to_polynomial() by the use of maps instead of lists. The old forms subs(const lst & ls, const lst & lr, unsigned options) to_rational/to_polynomial(lst & repl) are still available for compatibility, but using the new forms subs(const exmap & m, unsigned options) to_rational/to_polynomial(exmap & repl) is more efficient, especially when the number of replacements is large. * quo(), rem(), prem(), sprem(), decomp_rational(), unit(), content(), primpart() and matrix::charpoly() now take a "const ex &" instead of a "const symbol &". * Redundant expressions (two ex pointing to different objects are found to be equal in compare()) are now actively deleted/fused to conserve memory and speed up subsequent comparisons. This behavior can be suppressed on a per-object level with status_flags::not_shareable. Lists and matrices are not shareable by default. * Lots of internal streamlining and optimizations. * Caveats for class implementors: - basic::copy() and basic::destroy() are gone; classes derived from basic can use the defaults for the assignment operator and copy constructor. - basic::subs(), basic::normal(), basic::to_rational() and basic::to_polynomial() take 'exmap' objects instead of lists. - basic::subs() now descends into subexpressions (if accessible via nops()/op()/let_op()). If you have a custom implementation of subs() that calls basic::subs() after substituting subexpressions, this needs to be changed to a call to subs_one_level(). - lst::thislst() and exprseq::thisexprseq() renamed to thiscontainer(). - thiscontainer() and associated constructors now take a std::auto_ptr. - Overloading basic::print() is now deprecated. You should use print_func<>() class options instead. 1.1.7 (11 March 2004) * Fixed a bug in canonicalize_clifford(). * Series expansion now works predictably. All terms with the exponent of the expansion variable smaller than the given order are calculated exactly. If the series is not terminating, the Order function is (at least) of the given order. 1.1.6 (22 January 2004) * Added a function option "dummy()" which means "no options". This simplifies the implementation of symbolic functions which are not to be further evaluated. * Removed a bug in the numerical evaluation of Li() that caused the system to hang for certain parameter combinations. * Fixed a bug in the calculation of hash values for indices that could lead to wrong results or bogus error messages from simplify_indexed(). * Fixed a bug in the evaluation of harmonic polylogarithms for complex arguments with positive imaginary part. 1.1.5 (5 November 2003) * Harmonic polylogarithms now numerically evaluate for arbitrary arguments (parameter must still be positive integers). * The zeta function now can also be given a lst as a parameter in which case it becomes a multiple zeta value. The use of mZeta is deprecated. * The order of parameters for the multiple polylogarithm has been corrected. * Documentation for the nested sums functions zeta, harmonic polylog, multiple polylog, etc. has been added. 1.1.4 (17 October 2003) * Lists and matrices can now be initialized from comma-separated lists of expressions, like this: lst l; l = x, 2, y, x+y; matrix M(3, 3); M = x, y, 0, -y, x, 0, 0, 0, 1; This is both faster and produces much smaller code than the old constructors lst(ex, ex, ...) and matrix(unsigned, unsigned, lst), especially in the case of matrices, and is now the recommended way to create these objects. * The function mZeta now evaluates much faster for arbitrary parameters. The harmonic and multiple polylogarithms evaluate considerably faster and check for convergence. The order of parameters for the harmonic polylogarithm has been corrected. 1.1.3 (22 August 2003) * Added new symbolic functions for better integration with nestedsums: (multiple) polylogarithm Li(), Nielsen's generalized polylogarithm S(), harmonic polylogarithm H(), and multiple zeta value mZeta(). * New exhashmap template intended as a drop-in replacement for std::map using GiNaC's hashing algorithms. 1.1.2 (11 August 2003) * Fixed a bug in the unarchiving of sums and products: terms were not reordered in a canonical way. * Fixed a bug in normal()/numer_denom(): denominator was not made unit normal if it was a simple number. * Improved the speed of subs() in some cases. 1.1.1 (18 June 2003) * lst (and exprseq) provide iterators for read-only element access. For sequential access this is one order faster than using op(). * Implemented relational::subs() (this was done in 1.0.9 but inadvertently omitted from the 1.1 branch). * pole_error and do_taylor are available to library users. * Added on-line help and Tab-completion for print(), iprint(), print_latex() and print_csrc() in ginsh. 1.1.0 (3 April 2003) * Removed deprecated macros is_ex_a, is_ex_exactly_a and friends for good. * The scalar_products mechanism allows the specification of an index dimension. * Removed dirac_gamma6/7(). * Added ex::to_polynomial(). * subs() accepts an optional "options" argument. The option subs_option::subs_algebraic enables "smart" substitutions in products and powers. * Added stream manipulators "dflt", "latex", "python", "python_repr", "tree", "csrc", "csrc_float", "csrc_double", "csrc_cl_N", "index_dimensions" and "no_index_dimensions" to control the output format. Calling basic::print() directly is now deprecated. * Made the hashing more simple and efficient. * Caveats for class implementors: - basic::subs(): third argument changed from "bool" to "unsigned" - unarchiving constructor and basic::unarchive(): "const" removed from second argument - basic::let_op() should only be implemented if write access to subexpressions is desired - simplify_ncmul() renamed to eval_ncmul() - simplified_ncmul() renamed to hold_ncmul() - nonsimplified_ncmul() renamed to reeval_ncmul() 1.0.14 (1 March 2003) * Improved the C-source output: complex numbers are printed correctly (using the STL complex<> template or cln::complex()), rational numbers use cl_RA() in the CLN output, and small integers are printed in a more compact format (e.g. "2.0" instead of "2.0000000e+00"). * function_options::set_return_type() and function_options::do_not_evalf_params() now actually work. 1.0.13 (27 January 2003) * Contracting epsilon tensors with Euclidean indices now works. * Improved dummy index symmetrization in sums. * Added dirac_gammaL/R(), which can be used instead of dirac_gamma6/7() but are single objects, to allow for a more compact notation of Dirac strings. * Powers with negative numeric exponents are printed as fractions in the LaTeX output. * Added symbolic_matrix() for the convenient creation of matrices filled with symbols. * Added collect_common_factors() which collects common factors from the terms of sums. * simplify_indexed() converts "gamma~mu*p.mu" to "p\". 1.0.12 (30 October 2002) * Fixed a bug in power::expand() that could produce invalid expressions. * The input parser no longer ignores extra data following accepted input. * Improved the CLN C-source output (integers are printed as integers, and floating point numbers include the precision). * Fixed a problem in the LaTeX-output of negative fractions. * Added print_latex() and print_csrc() to ginsh. * The sprem() function is now public. 1.0.11 (18 September 2002) * Fixed a possible memory corruption in contractions of indexed objects with delta or metric tensors. * Computing the derivative of a power series object with respect to a symbol that is not the expansion variable now works correctly. * Several bugfixes in code generation. 1.0.10 (24 July 2002) * Powers of indexed objects are now parenthesized correctly in LaTeX output. * Input parser handles indices (they have to be specified in the same list as the symbols). * Added some limited support for subspaces in the idx and tensor classes. * Fixed a bug in canonicalize() (antisymmetric canonicalization of an already sorted list containing two or more equal objects failed to return 0). 1.0.9 (11 June 2002) * simplify_indexed() now raises/lowers dummy indices to canonicalize the index variance. This allows some simplifications that weren't possible before, like eps~a.b~c~d*X.a*X~b -> 0 and X.a~a-X~a.a -> 0. * Implemented relational::subs(). * Fixed bug in simplify_ncmul() for clifford objects. 1.0.8 (31 March 2002) * Improvements in memory usage of the expand() methods. 1.0.7 (18 March 2002) * Fixed LaTeX output of indexed and matrix objects. * Fixed matrix::pow(n) for n==0 and added helper functions to create unit matrices "ex unit_matrix(unsigned, unsigned)". 1.0.6 (4 March 2002) * "(x+1).subs(x==x-1)" now returns the correct result "x" instead of "x-1". 1.0.5 (27 January 2002) * (l)degree(s), coeff(s, n) and collect(s) were extended to accept expressions of any class (except add/mul/ncmul/numeric) for "s". They should even work if "s" is a "power" object, as long as the exponent is non-integer, but with some limitations. For example, you can "collect(a*2^x+b*2^x, 2^x)" to get "(a+b)*2^x", but "degree(2^(3*x), 2^x)" yields 0 instead of 3). * Fixed a small output bug. 1.0.4 (24 January 2002) * Speedup in expand(). * Faster Bernoulli numbers (Markus Nullmeier). * Some minor bugfixes and documentation updates. 1.0.3 (21 December 2001) * Fixed a bug where quo() would call vector::reserve() with a negative argument. * Fix several bugs in code generation. 1.0.2 (19 December 2001) * Input parser recognizes "sqrt()", which is also used in the output. * divide(a,b,q) only modifies q if the division succeeds; also, divide(a,b,a) works now. * Fixed small bug in dummy index renaming which could cause it to not recognize renamable indices in some cases. * power::degree() and power::ldegree() throw an exception when encountering a non-integer exponent. * Add output-support for Python bindings. 1.0.1 (22 November 2001) * Function sqrfree() handles a few more cases now. * Class relational has real canonical ordering now. * Handle obscene libreadline version numbers when building ginsh. 1.0.0 (6 November 2001) * Some internal reorganization resulting in a general speed-up. * The last 3 evaluated expressions in ginsh are now referred to with the tokens '%', '%%' and '%%%'. The old '"', '""' and '"""' remain for compatibility but may be removed in a future version of GiNaC. 0.9.4 (20 September 2001) * Functions have better support for external scripting languages. * Interface cleanups and bugfixes. * Fix silly bug in evalf() that prevented things like 2^Pi being computed. 0.9.3 (16 August 2001) * series expansion now much more consistent for small order expansion. * lsolve() accepts algorithmic hint as parameter. 0.9.2 (31 July 2001) * Epsilon tensor is more functional. * simplify_indexed() is better at detecting expressions that vanish for symmetry reasons. * Several little bugfixes and consistency enhancements. 0.9.1 (27 June 2001) * Ctors of class numeric are not explicit any more. All built-in callers for pseudofunctions are now templated and default to ex arguments which relaxes the need for explicit ctors. * New functions/methods: - find() - remove_first(), remove_last(), sort() and unique() for lists - symmetrize_cyclic() - decomp_rational() * Instead of just totally symmetric or antisymmetric, complex symmetries can now be defined for indexed objects. Symmetries are described by a tree of "symmetry" objects that is constructed with the sy_none(), sy_symm(), sy_anti() and sy_cycl() functions. The symmetry of a function with respect to its arguments can also be defined (this is currently only used for the Beta function). * Generalized map() to take a function object instead of a function pointer. This allows passing an arbitrary number of additional state to the function being called. * color_trace(), dirac_trace(), diff(), expand(), evalf() and normal() work better with container classes, e.g. using color_trace() on a relation will take the trace on both sides, using diff() on a matrix differentiates every element etc. * diff() works properly with non-commutative products and indexed objects. * New option flag "expand_function_args" for expand(). * Supplement some (now deprecated) macros by inlined template functions: - is_of_type(foo, type) -> is_a(foo) - is_ex_of_type(foo, type) -> is_a(foo) - is_exactly_of_type(foo, type) -> is_exactly_a(foo) - is_ex_exactly_of_type(foo, type) -> is_exactly_a(foo) - ex_to_foobar(baz) -> ex_to(baz) * rem(c, p[x], x) (c: numeric, p[x]: polynomial) erroneously returned p[x] instead of c. * Small bugfixes in pattern matching. * Updated libtool to version 1.4. 0.9.0 (7 June 2001) * In the output and in ginsh, lists are now delimited by { } braces, and matrices are delimited by single [ ] brackets. * simplify_indexed() renames dummy indices so, e.g., "a.i*a.i+a.j*a.j" gets simplified to "2*a.i*a.i" (or "2*a.j*a.j"). * New functions/methods: - canonicalize_clifford() (helpful when comparing expressions containing Dirac matrices) - symmetrize() and antisymmetrize() - numer_denom() (return numerator and denominator in one call) - map() (apply function to subexpressions) - evalm() (evaluate sums, products and integer powers of matrices) * Added a new function match() for performing pattern matching. subs() and has() also accept patterns as arguments. A pattern can be any expression, optionally containing wildcard objects. These are constructed with the call "wild()" and are denoted as "$0", "$1" etc. in the output and in ginsh. * Positive integer powers of non-commutative expressions (except matrices) are automatically expanded. * Removed cint subdirectory, ginaccint is a separate package now due to packaging considerations. * Several little bugfixes. 0.8.3 (11 May 2001) * color and clifford classes are functional and documented. * New "spinidx" class for dotted/undotted indices. * Predefined spinor metric tensor (created by spinor_metric()). * Symbols can have a LaTeX name, e.g. symbol s("s", "\\sigma"); * LaTeX output of indexed objects is much nicer. * Fixed some build problems (with recent libreadline). * Semantics of arithmetic operators now follows the C++ rules more strictly. 0.8.2 (24 April 2001) * degree(), ldegree(), coeff(), lcoeff(), tcoeff() and collect() work with non-symbols as the second argument in ginsh. * the argument to collect() can be a list of objects in which case the result is either a recursively collected polynomial, or a polynomial in a distributed form with terms like coeff*x1^e1*...*xn^en, as specified by the second argument to collect(). * Several bugfixes (including a nasty memory leak in .normal()). * class matrix: solve() doesn't call algorithms redundantly any more and inverse() falls back to solve() which works in more general cases. 0.8.1 (16 April 2001) * degree(), ldegree(), coeff(), lcoeff(), tcoeff() and collect() can now be used with constants, functions and indexed expressions as well, so you can use it to collect by powers of Pi or sin(x), or to find the coefficient of gamma~0. Limitations: - it only works with symbols, constants, functions and indexed expressions, trying to find the coefficient of, e.g., "x^2" or "x+y" won't work; - it does not know about dummy index summations; the coefficient of gamma~0 in p.mu*gamma~mu should be p.0 but is returned as 0; - using coeff(), tcoeff(), lcoeff() or collect() on elements of noncommutative products might return wrong or surprising results. * subs() no longer only substitutes symbols and indices but performs a more general "syntactic substitution", i.e. it substitutes whole objects in sub- expressions. You can subs((a+b)^2,a+b==3) and get 9, but subs(a+b+c,a+b==3) doesn't do anything. Limitations: - substituting numerics (subs(expr, 2==4)) will not replace then in all occurrences; in general, you shouldn't substitute numerics, though. * Added preliminary (re)implementations of color and clifford classes. * simplify_indexed(): contraction of symmetric and antisymmetric tensors is zero. * Replaced the various print*() member functions by a single print() that takes a print_context object that determines the output formatting. This should make it easier to add more output types, such as LaTeX output, which is based on work by Stefan Weinzierl. * Added functions to retrieve the properties stored in archive objects outside of unarchive() (for printing or debugging purposes). * Some bugfixes (indexed objects, archive writing). * .collect() on non-polynomials is now algebraically correct. 0.8.0 (24 March 2001) * Complete revamp of indexed objects. Instead of multiple classes for indexed things and their indices there is now only one "indexed" class and two types of indices: "idx" for simple indices and "varidx" for indices with variance. There are predefined delta, epsilon and metric tensors, and a function simplify_indexed() that performs canonicalization and dummy index summations. Matrix objects can be indexed for doing simple linear algebra. * Added an option "expand_indexed" to expand() to perform expansion of indexed objects like (a+b).i -> a.i + b.i * Renamed get_indices() to get_free_indices(), which no longer returns dummy indices and checks the consistency of indices in sums. * sqrfree() factorization fixed and improved syntactically. * subs() works on matrices. * Matrices can be constructed from flat list of elements; diagonal matrices can be constructed from list of diagonal elements with diag_matrix(). * Fixed memory leak in expand(). * Operator% for objects of class ncmul has gone. Use operator* now for that case too, which is much more natural. 0.7.3 (28 February 2001) * Several bugfixes and minor performance tunings. * Added a section to the tutorial about adding new algebraic classes to GiNaC. * Closed many in-source documentation gaps. 0.7.2 (17 February 2001) * Several bugfixes in power series expansion, one of them critical. 0.7.1 (7 February 2001) * Fix problems with Cint that were caused by CLN's overloaded operator new. * Fix compilation errors with GCC3. * normal() handles large sums of fractions better and normalizes the exponent of power expressions. * expand() always expands the exponent and transforms x^(a+b) -> x^a*x^b. * Some bugfixes of series expansion around branch cuts of special functions. 0.7.0 (15 December 2000) * Requires CLN 1.1 now. Class numeric doesn't use an indirect pointer to the actual representation any more. This is a speedup. * mul::expand() was reengineered to not allocate excess temporary memory. * Non-integer powers of a symbol are treated as constants by (l)degree() and coeff(). Using these functions on an expression containing such powers used to fail with an internal error message. The side-effect is that collect() can be used on expressions which are not polynomials. * Added a man page for the ginac-config script. * Ctor of numeric from char* honors Digits. 0.6.4 (10 August 2000) * Complete revamp of methods in class matrix. Some redundant (and poor) implementations of elimination schemes were thrown out. The code is now highly orthogonal, more flexible and much more efficient. * Some long standing and quite nasty bugs were discovered and fixed in the following functions: add::normal(), heur_gcd(), sr_gcd() and Order_eval(). 0.6.3 (25 July 2000) * Derivatives are now assembled in a slightly different manner (i.e. they might 'look' different on first sight). Under certain circumstances this can result in a dramatic speedup because it gives hashing a better chance, especially when computing higher derivatives. * Some series expansions of built-in functions have been reengineered. * The algorithm for computing determinants can be chosen by the user. See ginac/flags.h and ginac/matrix.h. * The Dilogarithm (Li2) now has floating point evaluation, derivative and a proper series expansion. * Namespace 'std' cleanly disentangled, as demanded by ISO/EIC 14882-1998(E). * Some minor bugfixes, one major lsolve()-bugfix and documentation updates. 0.6.2 (21 June 2000) * ginaccint.bin is now launched by a binary program instead of by a scripts. This allows us to write #!-scripts. A small test suite for GiNaC-cint was added. * Several minor bugfixes. 0.6.1 (18 May 2000) * Cleanup in the interface to Cint. The required version is now Cint 5.14.38. * Several bugfixes in target install. 0.6.0 (11 May 2000) * IMPORTANT: Several interface changes make programs written with GiNaC much clearer but break compatibility with older versions: - f(x).series(x,p[,o]) -> f(x).series(x==p,o) - series(f(x),x,p[,o]) -> series(f(x),x==p,o) - gamma() -> tgamma() (The true Gamma function, there is now also log(tgamma()), called lgamma(), in accord with ISO/IEC 9899:1999.) - EulerGamma -> Euler * #include'ing ginac.h defines the preprocessor symbols GINACLIB_MAJOR_VERSION, GINACLIB_MINOR_VERSION, and GINACLIB_MICRO_VERSION with the respective GiNaC library version numbers. * Expressions can be constructed from strings like this: ex e("2*x+y", lst(x, y)); * ex::to_rational() provides a way to extend the domain of functions like gcd() and divide() that only work on polynomials or rational functions (the good old ex::subs() method reverses this process) * Calling diff() on a function that has no derivative defined returns the inert derivative function "Derivative". * Several new timings in the check target. Some of them may be rather rude at your machine, feel free to interrupt them. 0.5.4 (15 March 2000) * Some algorithms in class matrix (notably determinant) were replaced by less brain-dead ones and should now have much better performance. * Checks were completely reorganized and split up into three parts: a) exams (small regression tests with predefined input) b) checks (lengthy coherence checks with random input) c) timings (for coherence and crude benchmarking) * Behaviour of .evalf() was changed: it doesn't .evalf() any exponents. * Expanded expressions now remember they are expanded to prevent superfluous expansions. * Small bugfixes and improvements in the series expansion. 0.5.3 (23 February 2000) * A more flexible scheme for registering functions was implemented, allowing for remembering, too. * Some Bugfixes. 0.5.2 (16 February 2000) * Mainly fixes a bug in the packaging of release 0.5.1. 0.5.1 (14 February 2000) * Fixes a small number of bugs. 0.5.0 (7 February 2000) * Expressions can be written ("archived") to files and read from there. * Addition of GiNaC-cint, which lets you write complete programs in an interactive shell-like manner in your favoured programming language (i.e. C++). 0.4.1 (13 December 1999) * Series Expansion of Gamma function and some other trigonometric functions at their poles works now. * Many more evaluations of special functions at points where exact results exist. * info_flags::rational doesn't return true for complex extensions any more---use info_flags::crational for the old behaviour. info_flags::integer and -::cinteger work similarly, the same holds for types like info_flags::rational_polynomial. 0.4.0 (26 November 1999) * First public release. pynac-pynac-0.7.29/PACKAGING.md000066400000000000000000000014231406646613100156500ustar00rootroot00000000000000Don't package versions that are newer than the one in the newest Sage beta. If you really insist don't use github's default tarballs, use the one that is created with "make dist", which is always on top of the release tarball list. ### Why not package newer versions? Pynac is not an independent library. Every Pynac version is associated with a specific Sage version, because the library interface changes frequently. Versions that are newer than the one in the newest Sage beta may need the Pynac upgrade ticket branch in Sage trac (search for pynac). The upgrade ticket also always has a link to the correct official Pynac tarball. The ticket may also have last-minute fixes as patches---of course they are also in Pynac-github master but they probably don't warrant a new release. pynac-pynac-0.7.29/README000066400000000000000000000040731406646613100147260ustar00rootroot00000000000000Pynac -- "Python is Not a CAS" is a modified version of Ginac that replaces the dependency of GiNaC on CLN by a dependency instead of Python. It is a lite version of GiNaC as well, not implementing all the features of the full GiNaC, and it is *only* meant to be used as a Python library. -- William Stein ORIGINAL README General Information =================== GiNaC (which stands for "GiNaC is Not a CAS" (computer algebra system)) is a C++ library for symbolic mathematical calculations. It is designed to allow the creation of integrated systems that embed symbolic manipulations together with more established areas of computer science (like computation-intense numeric applications, graphical interfaces, etc.) under one roof. The official ftp site is: ftp://ftpthep.physik.uni-mainz.de/pub/GiNaC/ The official web site is: http://www.ginac.de/ A mailing list is located at: ginac-list@ginac.de You need to be subscribed to be able to post to the list. To subscribe, please follow the instructions on https://www.cebix.net/mailman/listinfo/ginac-list See http://www.ginac.de/Lists.html for the list policy. Installation ============ See the file "INSTALL". How to report bugs ================== If you have identified a bug in GiNaC you are welcome to send a detailed bug report to . Please think about your bug! This means that you should include * Information about your system - Which operating system and version (uname -a) - Which C compiler and version (gcc --version) - For Linux, which version of the C library And anything else you think is relevant. * Information about your version of GiNaC - Version and release number - Which options GiNaC was configured with * How to reproduce the bug - If it is a systematical bug in the library, a short test program together with the output you get and the output you expect will help us to reproduce it quickly. Patches are most welcome. If possible please make them with diff -c and include ChangeLog entries. Join the chat at https://gitter.im/pynac/pynac pynac-pynac-0.7.29/acinclude.m4000066400000000000000000000116141406646613100162360ustar00rootroot00000000000000dnl =========================================================================== dnl Additional macros used to configure GiNaC. We don't start our own dnl additions' names with AC_ but with GINAC_ in order to steer clear of dnl future trouble. dnl =========================================================================== dnl Usage: GINAC_RLVERSION dnl The maintainers of libreadline are complete morons: they don't care a shit dnl about compatibility (which is not so bad by itself) and at the same time dnl they don't export the version to the preprocessor so we could kluge around dnl incompatibilities. The only reliable way to figure out the version is by dnl checking the extern variable rl_library_version at runtime. &#@$%*! AC_DEFUN([GINAC_LIB_READLINE_VERSION], [AC_CACHE_CHECK([for version of libreadline], ginac_cv_rlversion, [ AC_TRY_RUN([ #include #include #include int main() { FILE *fd; fd = fopen("conftest.out", "w"); fprintf(fd, "%s\n", rl_library_version); fclose(fd); return 0; }], [ dnl Some non-GNU readline implementations have non-numeric rl_library_version ginac_cv_rlversion=`sed -e 's/[[^0-9.]]//g' 'conftest.out'`], [ ginac_cv_rlversion='unknown'], [ ginac_cv_rlversion='4.2'])]) if test -z "$ginac_cv_rlversion"; then GINAC_WARNING([Unsupported version of libreadline.]) ginac_cv_rlversion='unknown' fi if test "x${ginac_cv_rlversion}" != "xunknown"; then AC_DEFINE(REALLY_HAVE_LIBREADLINE, ,[Define if GNU libreadline is installed]) RL_VERSION_MAJOR=`echo ${ginac_cv_rlversion} | sed -e 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` AC_DEFINE_UNQUOTED(GINAC_RL_VERSION_MAJOR, $RL_VERSION_MAJOR, [Major version of installed readline library.]) RL_VERSION_MINOR=`echo ${ginac_cv_rlversion} | sed -e 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` AC_DEFINE_UNQUOTED(GINAC_RL_VERSION_MINOR, $RL_VERSION_MINOR, [Minor version of installed readline library.]) else GINAC_WARNING([I could not run a test of libreadline (needed for building ginsh).]) fi ]) dnl Usage: GINAC_TERMCAP dnl libreadline is based on the termcap functions. dnl Some systems have tgetent(), tgetnum(), tgetstr(), tgetflag(), tputs(), dnl tgoto() in libc, some have it in libtermcap, some have it in libncurses. dnl When both libtermcap and libncurses exist, we prefer the latter, because dnl libtermcap is being phased out. AC_DEFUN([GINAC_TERMCAP], [LIBTERMCAP= case $host_os in *mingw32*) ;; dnl no termcap libraries are necessary (need hacked libreadline) *) AC_CHECK_FUNCS(tgetent) if test "x$ac_cv_func_tgetent" = "xyes"; then : else AC_CHECK_LIB(ncurses, tgetent, LIBTERMCAP="-lncurses") if test -z "$LIBTERMCAP"; then AC_CHECK_LIB(termcap, tgetent, LIBTERMCAP="-ltermcap") fi fi ;; esac AC_SUBST(LIBTERMCAP) ]) dnl Usage: GINAC_ERROR(message) dnl This macro displays the warning "message" and sets the flag ginac_error dnl to yes. AC_DEFUN([GINAC_ERROR],[ ginac_error_txt="$ginac_error_txt ** $1 " ginac_error=yes]) dnl Usage: GINAC_WARNING(message) dnl This macro displays the warning "message" and sets the flag ginac_warning dnl to yes. AC_DEFUN([GINAC_WARNING],[ ginac_warning_txt="$ginac_warning_txt == $1 " ginac_warning=yes]) dnl Usage: GINAC_CHECK_ERRORS dnl (must be put at end of configure.in, because it exits on error) dnl This macro displays a warning message if GINAC_ERROR or GINAC_WARNING dnl has occurred previously. AC_DEFUN([GINAC_CHECK_ERRORS],[ if test "x${ginac_error}" = "xyes"; then echo "**** The following problems have been detected by configure." echo "**** Please check the messages below before running \"make\"." echo "**** (see the section 'Common Problems' in the INSTALL file)" echo "$ginac_error_txt" if test "x${ginac_warning_txt}" != "x"; then echo "${ginac_warning_txt}" fi if test "x$cache_file" != "x/dev/null"; then echo "deleting cache ${cache_file}" rm -f $cache_file fi exit 1 else if test "x${ginac_warning}" = "xyes"; then echo "=== The following minor problems have been detected by configure." echo "=== Please check the messages below before running \"make\"." echo "=== (see the section 'Common Problems' in the INSTALL file)" echo "$ginac_warning_txt" fi echo "Configuration of GiNaC $VERSION done. Now type \"make\"." fi]) AC_DEFUN([GINAC_HAVE_RUSAGE], [AC_CACHE_CHECK([whether struct rusage is declared in ], ac_cv_have_rusage, [AC_TRY_COMPILE([#include #include ], [struct rusage resUsage; getrusage(RUSAGE_SELF, &resUsage); return 0;], [ac_cv_have_rusage=yes], [ac_cv_have_rusage=no]) ]) CONFIG_RUSAGE="no" if test "$ac_cv_have_rusage" = yes; then CONFIG_RUSAGE="yes" AC_DEFINE(HAVE_RUSAGE,,[define if struct rusage declared in ]) fi AC_SUBST(CONFIG_RUSAGE) ]) pynac-pynac-0.7.29/bootstrap000077500000000000000000000002001406646613100157750ustar00rootroot00000000000000#!/bin/sh set -e aclocal --force -I m4 libtoolize --copy --force autoconf --force autoheader --force automake --add-missing pynac-pynac-0.7.29/compile_commands.json000066400000000000000000000674541406646613100202660ustar00rootroot00000000000000[ { "command": "clang++ -c -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-constant.o /home/ralf/sage/pynac/ginac/constant.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/constant.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-basic.o /home/ralf/sage/pynac/ginac/basic.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/basic.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-add.o /home/ralf/sage/pynac/ginac/add.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/add.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-useries.o /home/ralf/sage/pynac/ginac/useries.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/useries.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-cmatcher.o /home/ralf/sage/pynac/ginac/cmatcher.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/cmatcher.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-ex.o /home/ralf/sage/pynac/ginac/ex.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/ex.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-expair.o /home/ralf/sage/pynac/ginac/expair.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/expair.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-expairseq.o /home/ralf/sage/pynac/ginac/expairseq.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/expairseq.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-fderivative.o /home/ralf/sage/pynac/ginac/fderivative.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/fderivative.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-function.o /home/ralf/sage/pynac/ginac/function.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/function.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-infinity.o /home/ralf/sage/pynac/ginac/infinity.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/infinity.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns.o /home/ralf/sage/pynac/ginac/inifcns.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_trig.o /home/ralf/sage/pynac/ginac/inifcns_trig.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_trig.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_zeta.o /home/ralf/sage/pynac/ginac/inifcns_zeta.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_zeta.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_hyperb.o /home/ralf/sage/pynac/ginac/inifcns_hyperb.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_hyperb.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_trans.o /home/ralf/sage/pynac/ginac/inifcns_trans.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_trans.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_gamma.o /home/ralf/sage/pynac/ginac/inifcns_gamma.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_gamma.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_nstdsums.o /home/ralf/sage/pynac/ginac/inifcns_nstdsums.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_nstdsums.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_orthopoly.o /home/ralf/sage/pynac/ginac/inifcns_orthopoly.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_orthopoly.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-matrix.o /home/ralf/sage/pynac/ginac/matrix.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/matrix.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-mul.o /home/ralf/sage/pynac/ginac/mul.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/mul.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-normal.o /home/ralf/sage/pynac/ginac/normal.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/normal.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-numeric.o /home/ralf/sage/pynac/ginac/numeric.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/numeric.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-operators.o /home/ralf/sage/pynac/ginac/operators.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/operators.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-relational.o /home/ralf/sage/pynac/ginac/relational.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/relational.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-power.o /home/ralf/sage/pynac/ginac/power.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/power.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-remember.o /home/ralf/sage/pynac/ginac/remember.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/remember.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-symbol.o /home/ralf/sage/pynac/ginac/symbol.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/symbol.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-pseries.o /home/ralf/sage/pynac/ginac/pseries.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/pseries.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-symmetry.o /home/ralf/sage/pynac/ginac/symmetry.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/symmetry.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-utils.o /home/ralf/sage/pynac/ginac/utils.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/utils.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-assume.o /home/ralf/sage/pynac/ginac/assume.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/assume.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-wildcard.o /home/ralf/sage/pynac/ginac/wildcard.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/wildcard.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-registrar.o /home/ralf/sage/pynac/ginac/registrar.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/registrar.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-order.o /home/ralf/sage/pynac/ginac/order.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/order.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-archive.o /home/ralf/sage/pynac/ginac/archive.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/archive.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-print.o /home/ralf/sage/pynac/ginac/print.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/print.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-exprseq.o /home/ralf/sage/pynac/ginac/exprseq.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/exprseq.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-infoflagbase.o /home/ralf/sage/pynac/ginac/infoflagbase.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/infoflagbase.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-templates.o /home/ralf/sage/pynac/ginac/templates.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/templates.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-function_info.o /home/ralf/sage/pynac/ginac/function_info.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/function_info.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_comb.o /home/ralf/sage/pynac/ginac/inifcns_comb.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_comb.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-inifcns_hyperg.o /home/ralf/sage/pynac/ginac/inifcns_hyperg.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/inifcns_hyperg.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-lst.o /home/ralf/sage/pynac/ginac/lst.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/lst.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-mpoly.o /home/ralf/sage/pynac/ginac/mpoly.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/mpoly.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-mpoly-ginac.o /home/ralf/sage/pynac/ginac/mpoly-ginac.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/mpoly-ginac.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-mpoly-giac.o /home/ralf/sage/pynac/ginac/mpoly-giac.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/mpoly-giac.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-mpoly-singular.o /home/ralf/sage/pynac/ginac/mpoly-singular.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/mpoly-singular.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-py_funcs.o /home/ralf/sage/pynac/ginac/py_funcs.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/py_funcs.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-sum.o /home/ralf/sage/pynac/ginac/sum.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/sum.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-upoly-ginac.o /home/ralf/sage/pynac/ginac/upoly-ginac.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/upoly-ginac.cpp" }, { "command": "clang++ -c -DHAVE_CONFIG_H -I/home/ralf/sage/pynac/ginac -I/home/ralf/sage/pynac -DGCC_INSTALL_PREFIX=/home/ralf/sage/local/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ -I/home/ralf/sage/local/include -I/home/ralf/sage/local/include/python2.7 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -g -O2 -std=c++11 -stdlib=libc++ -o libpynac_la-context.o /home/ralf/sage/pynac/ginac/context.cpp", "directory": "/home/ralf/sage/pynac/ginac", "file": "/home/ralf/sage/pynac/ginac/context.cpp" } ] pynac-pynac-0.7.29/configure.ac000066400000000000000000000207531406646613100163370ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. dnl GiNaC library version information. dnl dnl When making releases do whatever you want with the major, dnl minor and micro project version numbers ; but for the library dnl version, you must be more careful (the following lines are dnl to be read as an algorithm, don't stop at the first one!) : dnl 1. increment lt_revision dnl 2. if any interface has been added, removed or modified since the dnl last release, then increment lt_current and set lt_revision to 0 dnl 3. if any interface has been added, then increment lt_age dnl 4. if any interface has been removed, then set lt_age to zero dnl dnl In case you wonder why such instructions: dnl http://www.sourceware.org/autobook/autobook/autobook_91.html#SEC91 dnl The following article is helpful too: dnl http://www.freesoftwaremagazine.com/articles/building_shared_libraries_once_using_autotools dnl if you change this YOU MUST also change the libtool version below m4_define([ginac_major_version], [0]) m4_define([ginac_minor_version], [7]) m4_define([ginac_micro_version], [29]) m4_define([lt_current], [21]) m4_define([lt_revision], [7]) m4_define([lt_age], [3]) m4_define([ginac_version], [ginac_major_version.ginac_minor_version.ginac_micro_version]) m4_define([ginac_release], [ginac_major_version.ginac_minor_version]) AC_INIT([pynac],[ginac_version],[]) AC_PREREQ([2.69]) AC_CONFIG_SRCDIR(ginac/basic.cpp) AC_CONFIG_HEADERS(config.h) dnl This defines PACKAGE and VERSION. AM_INIT_AUTOMAKE([gnu 1.7 dist-bzip2]) # Allow "configure --disable-maintainer-mode" to disable timestamp checking AM_MAINTAINER_MODE([enable]) AM_PATH_PYTHON([2.7]) dnl Adapted from CPython 3.8 cpython/Misc/python-config.in AC_MSG_CHECKING([for Python preprocessor flags]) PYTHON_CPPFLAGS=$($PYTHON - <@], [use giac for polynomial manipulations @<:@default=no@:>@ (experimental)])], [], [with_giac=no]) LIBGIAC= AS_IF([test "x$with_giac" != xno], [AC_CHECK_LIB([giac], [ConvertUTF16toUTF8], [AC_SUBST([LIBGIAC], ["-lgiac"]) AC_DEFINE([HAVE_LIBGIAC], [1], [Define if you have libgiac]) ], [if test "x$with_giac" != xcheck; then AC_MSG_FAILURE( [--with-giac was given, but test for giac failed]) fi ], -lgmp)]) dnl Check for data types which are needed by the hash function dnl (golden_ratio_hash). AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long long) AC_CHECK_SIZEOF(long double) AC_CHECK_SIZEOF(void *) dnl Make sure all the necessary standard headers are installed on the system. AC_CHECK_HEADER(iosfwd, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(iostream, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(vector, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(list, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(map, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(string, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(sstream, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(typeinfo, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(stdexcept, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(algorithm, , GINAC_ERROR([The standard header file could not be found.])) AC_CHECK_HEADER(limits, , GINAC_ERROR([The standard header file could not be found.])) if test "x$CONFIG_RUSAGE" = "xno"; then AC_CHECK_HEADER(ctime, , GINAC_ERROR([The standard header file could not be found.])) fi PKG_PROG_PKG_CONFIG dnl Find Singular's factory header and library with pkg-config PKG_CHECK_MODULES([FACTORY], [factory], [ dnl Found it ], [ dnl Debian renames factory to singular-factory, look for that PKG_CHECK_MODULES([SINGULAR_FACTORY], [singular-factory], [ FACTORY_CFLAGS="$SINGULAR_FACTORY_CFLAGS" FACTORY_LIBS="$SINGULAR_FACTORY_LIBS" ], [ AC_MSG_ERROR([This package needs libfactory]) ]) ]) AC_SUBST(FACTORY_CFLAGS) AC_SUBST(FACTORY_LIBS) dnl Check for utilities needed by the different kinds of documentation. dnl Documentation needs only be built when extending it, so never mind if it dnl cannot find those helpers: #AC_PATH_PROG(DOXYGEN, doxygen, "") #AM_CONDITIONAL(CONFIG_DOXYGEN, [test ! -z "$DOXYGEN"]) #AC_PATH_PROG(LATEX, latex, "") #AC_PATH_PROG(PDFLATEX, pdflatex, "") #AC_PATH_PROG(MAKEINDEX, makeindex, "") #AC_PATH_PROG(DVIPS, dvips, "") #AM_CONDITIONAL(CONFIG_TEX, [test ! \( -z "$LATEX" -o -z $"PDFLATEX" -o -z "$MAKEINDEX" -o -z "$DVIPS" \)]) #AC_PATH_PROG(FIG2DEV, fig2dev, "") #AM_CONDITIONAL(CONFIG_FIG2DEV, [test ! -z "$FIG2DEV"]) AC_PATH_PROG(RM, rm, $FALSE) RM="$RM -f" dnl Output makefiles etc. AC_CONFIG_FILES([ Makefile pynac.spec pynac.pc ginac/Makefile ginac/version.h ]) AX_PREFIX_CONFIG_H(ginac/pynac-config.h) AC_OUTPUT dnl Display a final warning if there has been a GINAC_ERROR or a GINAC_WARNING GINAC_CHECK_ERRORS pynac-pynac-0.7.29/ginac/000077500000000000000000000000001406646613100151235ustar00rootroot00000000000000pynac-pynac-0.7.29/ginac/Makefile.am000066400000000000000000000037221406646613100171630ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in lib_LTLIBRARIES = libpynac.la libpynac_la_SOURCES = add.cpp archive.cpp assume.cpp basic.cpp \ cmatcher.cpp constant.cpp context.cpp ex.cpp expair.cpp \ expairseq.cpp exprseq.cpp fderivative.cpp function.cpp function_info.cpp \ infinity.cpp inifcns.cpp inifcns_trig.cpp inifcns_zeta.cpp \ inifcns_hyperb.cpp inifcns_trans.cpp inifcns_gamma.cpp inifcns_nstdsums.cpp \ inifcns_orthopoly.cpp inifcns_hyperg.cpp inifcns_comb.cpp \ lst.cpp matrix.cpp mpoly-giac.cpp mpoly-ginac.cpp \ mpoly-singular.cpp mpoly.cpp mul.cpp normal.cpp numeric.cpp \ operators.cpp power.cpp py_funcs.cpp \ registrar.cpp relational.cpp remember.cpp \ pseries.cpp print.cpp symbol.cpp upoly-ginac.cpp \ utils.cpp wildcard.cpp templates.cpp infoflagbase.cpp sum.cpp \ remember.h tostring.h utils.h compiler.h order.cpp useries.cpp #The -no-undefined breaks Pynac on OS X 10.4. See #9135 if CYGWIN libpynac_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined else libpynac_la_LDFLAGS = -version-info $(LT_VERSION_INFO) endif libpynac_la_CPPFLAGS = $(PYTHON_CPPFLAGS) @FACTORY_CFLAGS@ -Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wno-unused-parameter -Wno-unknown-pragmas -Wno-parentheses-equality libpynac_la_LIBADD = $(PYTHON_LDFLAGS) $(LIBS) @FACTORY_LIBS@ $(LIBGIAC) ginacincludedir = $(includedir)/pynac ginacinclude_HEADERS = ginac.h py_funcs.h add.h archive.h assertion.h \ basic.h class_info.h cmatcher.h constant.h container.h context.h \ ex.h ex_utils.h expair.h expairseq.h exprseq.h \ fderivative.h flags.h function.h \ inifcns.h infinity.h lst.h matrix.h mpoly.h mul.h \ normal.h numeric.h operators.h optional.hpp \ power.h print.h pseries.h ptr.h registrar.h relational.h extern_templates.h \ symbol.h version.h wildcard.h order.h templates.h \ infoflagbase.h assume.h upoly.h useries.h useries-flint.h sum.h ginacinclude_HEADERS += pynac-config.h EXTRA_DIST = version.h.in DISTCLEANFILES = pynac-config.h pynac-pynac-0.7.29/ginac/add.cpp000066400000000000000000000576031406646613100163720ustar00rootroot00000000000000/** @file add.cpp * * Implementation of GiNaC's sums of expressions. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "add.h" #include "mul.h" #include "archive.h" #include "operators.h" #include "utils.h" #include "constant.h" #include "infinity.h" #include "compiler.h" #include "order.h" #include #include #include #include #include namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(add, expairseq, print_func(&add::do_print). print_func(&add::do_print_latex). print_func(&add::do_print_tree). print_func(&add::do_print_python_repr)) ////////// // default constructor ////////// add::add() { tinfo_key = &add::tinfo_static; } ////////// // other constructors ////////// // public add::add(const ex & lh, const ex & rh) { tinfo_key = &add::tinfo_static; overall_coeff = numeric(0); construct_from_2_ex(lh,rh); GINAC_ASSERT(is_canonical()); } add::add(const exvector & v, bool do_hold) { tinfo_key = &add::tinfo_static; overall_coeff = numeric(0); construct_from_exvector(v, do_hold); GINAC_ASSERT(is_canonical()); } add::add(const epvector & v) { tinfo_key = &add::tinfo_static; overall_coeff = numeric(0); construct_from_epvector(v); GINAC_ASSERT(is_canonical()); } add::add(const epvector & v, const numeric & oc) { tinfo_key = &add::tinfo_static; overall_coeff = oc; construct_from_epvector(v); GINAC_ASSERT(is_canonical()); } //add::add(std::unique_ptr vp, const ex & oc) //{ // tinfo_key = &add::tinfo_static; // GINAC_ASSERT(vp.get()!=0); // overall_coeff = oc; // construct_from_epvector(*vp); // GINAC_ASSERT(is_canonical()); //} ////////// // archiving ////////// DEFAULT_ARCHIVING(add) ////////// // functions overriding virtual functions from base classes ////////// // public void add::print_add(const print_context & c, unsigned level, bool latex) const { if (precedence() <= level){ if (latex) c.s << "{\\left("; else c.s << '('; } bool first = true; const epvector & sorted_seq = get_sorted_seq(); // Then proceed with the remaining factors for (const auto & elem : sorted_seq) { std::stringstream tstream; std::unique_ptr tcontext_p; if (latex) { tcontext_p.reset(new print_latex(tstream, c.options)); } else { tcontext_p.reset(new print_dflt(tstream, c.options)); } mul m = mul(elem.rest, elem.coeff); m.print(*tcontext_p, precedence()); if (!first) { if (tstream.peek() == '-') { tstream.ignore(); c.s << " - "; } else c.s << " + "; } else { first = false; } tstream.get(*(c.s.rdbuf())); } // Finally print the "overall" numeric coefficient, if present. // This is just the constant coefficient. if (not overall_coeff.is_zero()) { std::stringstream tstream; std::unique_ptr tcontext_p; if (latex) { tcontext_p.reset(new print_latex(tstream, c.options)); } else { tcontext_p.reset(new print_dflt(tstream, c.options)); } overall_coeff.print(*tcontext_p, 0); if (!first) { if (tstream.peek() == '-') { c.s << " - "; tstream.ignore(); } else c.s << " + "; } tstream.get(*(c.s.rdbuf())); } if (precedence() <= level) { if (latex) c.s << "\\right)}"; else c.s << ')'; } } void add::do_print(const print_context & c, unsigned level) const { print_add(c, level, false); } void add::do_print_latex(const print_latex & c, unsigned level) const { print_add(c, level, true); } void add::do_print_python_repr(const print_python_repr & c, unsigned /*level*/) const { c.s << class_name() << '('; op(0).print(c); for (size_t i=1; i deg) deg = t; } if (deg.is_negative() and not overall_coeff.is_zero()) return *_num0_p; return deg; } numeric add::ldegree(const ex & s) const { numeric deg(seq[0].rest.ldegree(s)); // Find minimum of degrees of individual terms for (const auto & elem : range(seq.begin()+1, seq.end())) { const numeric& t = elem.rest.ldegree(s); if (t < deg) deg = t; } if (deg.is_positive() and not overall_coeff.is_zero()) return *_num0_p; return deg; } ex add::coeff(const ex & s, const ex & n) const { epvector coeffseq; for (const auto & elem : seq) { ex restcoeff = elem.rest.coeff(s, n); if (!restcoeff.is_zero()) { coeffseq.emplace_back(restcoeff, elem.coeff); } } return (new add(coeffseq, n==0 ? overall_coeff : *_num0_p))->setflag(status_flags::dynallocated); } /** Perform automatic term rewriting rules in this class. In the following * x stands for a symbolic variables of type ex and c stands for such * an expression that contain a plain number. * - +(;c) -> c * - +(x;0) -> x * * @param level cut-off in recursive evaluation */ ex add::eval(int level) const { if ((level == 1) and is_evaluated()) { GINAC_ASSERT(seq.size()>0); GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_zero()); return *this; } std::unique_ptr evaled_seqp = evalchildren(level); if (unlikely(evaled_seqp != nullptr)) { // start over evaluating a new object return (new add(*evaled_seqp, overall_coeff))-> setflag(status_flags::dynallocated); } #ifdef DO_GINAC_ASSERT for (const auto & elem : seq) { GINAC_ASSERT(!is_exactly_a(elem.rest)); if (is_exactly_a(elem.rest)) dbgprint(); GINAC_ASSERT(!is_exactly_a(elem.rest)); } #endif // def DO_GINAC_ASSERT // handle infinity for (auto i = seq.begin(); i != seq.end(); i++) if (unlikely(is_exactly_a(i->rest))) return eval_infinity(i); /** Perform automatic term rewriting rules */ int seq_size = seq.size(); if (seq_size == 0) { // +(;c) -> c return overall_coeff; } if (seq_size == 1 && overall_coeff.is_zero()) { // +(x;0) -> x return recombine_pair_to_ex(*(seq.begin())); } else if (!overall_coeff.is_zero() && seq[0].rest.return_type() != return_types::commutative) { throw (std::logic_error("add::eval(): sum of non-commutative objects has non-zero numeric term")); } // if any terms in the sum still are purely numeric, then they are more // appropriately collected into the overall coefficient int terms_to_collect = 0; for (const auto & elem : seq) if (unlikely(is_exactly_a(elem.rest))) ++terms_to_collect; if (terms_to_collect != 0) { epvector s; s.reserve(seq_size - terms_to_collect); numeric oc = *_num0_p; for (const auto & elem : seq) if (unlikely(is_exactly_a(elem.rest))) oc = oc.add((ex_to(elem.rest)).mul(ex_to(elem.coeff))); else s.push_back(elem); return (new add(s, overall_coeff + oc)) ->setflag(status_flags::dynallocated); } return this->hold(); } namespace { // anonymous namespace infinity infinity_from_iter(epvector::const_iterator i) { GINAC_ASSERT(is_exactly_a(i->rest)); GINAC_ASSERT(is_a(i->coeff)); infinity result = ex_to(i->rest); result *= i->coeff; return result; } } // end anonymous namespace ex add::eval_infinity(epvector::const_iterator infinity_iter) const { GINAC_ASSERT(is_exactly_a(infinity_iter->rest)); infinity result = infinity_from_iter(infinity_iter); for (auto i = seq.begin(); i != seq.end(); i++) { if (not is_exactly_a(i->rest)) continue; if (i == infinity_iter) continue; infinity i_infty = infinity_from_iter(i); result += i_infty; } return result; } ex add::conjugate() const { epvector v; v.reserve(seq.size()); for (const auto & elem : seq) if ((elem.coeff).is_real() and (elem.rest).is_real()) { v.push_back(elem); } else { ex cj=recombine_pair_to_ex(elem).conjugate(); v.push_back(split_ex_to_pair(cj)); } // we know the conjugate is a numeric return (new add(v, overall_coeff.conj())) -> setflag(status_flags::dynallocated); } ex add::real_part() const { epvector v; v.reserve(seq.size()); for (const auto & elem : seq) if ((elem.coeff).is_real()) { ex rp = (elem.rest).real_part(); if (!rp.is_zero()) v.emplace_back(rp, elem.coeff); } else { ex rp=recombine_pair_to_ex(elem).real_part(); if (!rp.is_zero()) v.push_back(split_ex_to_pair(rp)); } return (new add(v, ex_to(overall_coeff.real_part()))) -> setflag(status_flags::dynallocated); } ex add::imag_part() const { epvector v; v.reserve(seq.size()); for (const auto & elem : seq) if ((elem.coeff).is_real()) { ex ip = (elem.rest).imag_part(); if (!ip.is_zero()) v.emplace_back(ip, elem.coeff); } else { ex ip=recombine_pair_to_ex(elem).imag_part(); if (!ip.is_zero()) v.push_back(split_ex_to_pair(ip)); } return (new add(v, ex_to(overall_coeff.imag_part()))) -> setflag(status_flags::dynallocated); } // protected /** Implementation of ex::diff() for a sum. It differentiates each term. * @see ex::diff */ ex add::derivative(const symbol & y) const { epvector s; s.reserve(seq.size()); // Only differentiate the "rest" parts of the expairs. This is faster // than the default implementation in basic::derivative() although // if performs the same function (differentiate each term). for (const auto & elem : seq) s.emplace_back(elem.rest.diff(y), elem.coeff); return (new add(s, *_num0_p))->setflag(status_flags::dynallocated); } int add::compare_same_type(const basic & other) const { return inherited::compare_same_type(other); } unsigned add::return_type() const { if (seq.empty()) return return_types::commutative; return seq.begin()->rest.return_type(); } tinfo_t add::return_type_tinfo() const { if (seq.empty()) return this; return seq.begin()->rest.return_type_tinfo(); } // Note: do_index_renaming is ignored because it makes no sense for an add. ex add::thisexpairseq(const epvector & v, const numeric & oc, bool /*do_index_renaming*/) const { return (new add(v,oc))->setflag(status_flags::dynallocated); } //// Note: do_index_renaming is ignored because it makes no sense for an add. ex add::thisexpairseq(std::unique_ptr vp, const numeric & oc, bool /*do_index_renaming*/) const { return (new add(*vp,oc))->setflag(status_flags::dynallocated); } expair add::split_ex_to_pair(const ex & e) const { if (is_exactly_a(e)) { const mul &mulref(ex_to(e)); const numeric &numfactor = mulref.overall_coeff; if (numfactor.is_one()) return expair(e, _ex1); auto mulcopyp = new mul(mulref); mulcopyp->overall_coeff = *_num1_p; mulcopyp->clearflag(status_flags::evaluated); mulcopyp->clearflag(status_flags::hash_calculated); mulcopyp->setflag(status_flags::dynallocated); return expair(*mulcopyp,numfactor); } return expair(e,_ex1); } expair add::combine_ex_with_coeff_to_pair(const ex & e, const numeric & c) const { if (is_exactly_a(e)) { const mul &mulref(ex_to(e)); const numeric &numfactor = mulref.overall_coeff; if (likely(numfactor.is_one())) return expair(e, c); auto mulcopyp = new mul(mulref); mulcopyp->overall_coeff = *_num1_p; mulcopyp->clearflag(status_flags::evaluated); mulcopyp->clearflag(status_flags::hash_calculated); mulcopyp->setflag(status_flags::dynallocated); if (c.is_one()) return expair(*mulcopyp, numfactor); return expair(*mulcopyp, numfactor*c); } else if (is_exactly_a(e)) { if (c.is_one()) return expair(e, _ex1); if (ex_to(e).is_one()) return expair(c, _ex1); return expair(ex_to(e)*c, _ex1); } return expair(e, c); } expair add::combine_pair_with_coeff_to_pair(const expair & p, const numeric & c) const { GINAC_ASSERT(is_exactly_a(p.coeff)); if (is_exactly_a(p.rest)) { GINAC_ASSERT(ex_to(p.coeff).is_one()); // should be normalized return expair(ex_to(p.rest).mul_dyn(c),_ex1); } return expair(p.rest,ex_to(p.coeff).mul_dyn(c)); } ex add::recombine_pair_to_ex(const expair & p) const { if (ex_to(p.coeff).is_one()) return p.rest; return (new mul(p.rest,p.coeff))->setflag(status_flags::dynallocated); } ex add::power(const numeric& expo) const { using POW = class power; numeric icont = integer_content(); const numeric lcoeff = ex_to(lead_coeff()).div(icont); if (not lcoeff.is_positive()) icont = icont.negative(); if (icont.is_one() or not lcoeff.is_integer()) return (new POW(*this, expo))-> setflag(status_flags::dynallocated | status_flags::evaluated); ex c; if (expo.is_integer()) { c = icont.pow_intexp(expo.to_long()); } else { bool ppower_equals_one; numeric newbasis, ppower; rational_power_parts(icont, expo, ppower, newbasis, ppower_equals_one); if (not newbasis.is_one() and (ppower_equals_one or icont.is_negative())) return (new POW(*this, expo))-> setflag(status_flags::dynallocated | status_flags::evaluated); if (ppower_equals_one) c = *_num1_p; else c = ppower * POW(newbasis, expo).hold(); } auto addp = new add(*this); addp->setflag(status_flags::dynallocated); addp->clearflag(status_flags::hash_calculated); addp->overall_coeff /= icont; addp->seq_sorted.resize(0); for (auto &elem : addp->seq) elem.coeff = ex_to(elem.coeff).div_dyn(icont); if (likely(not c.is_one())) return (new mul(POW(*addp, expo), c))-> setflag(status_flags::dynallocated | status_flags::evaluated); return (new POW(*addp, expo))-> setflag(status_flags::dynallocated | status_flags::evaluated); } // This is an alternative version of add::power that is necessary to // canonicalize powers of sums (always draws out the positive content). // It would be difficult to introduce this as general behaviour in Sage. ex Power(const ex& base_, const ex& expo_) { if (not is_exactly_a(base_) or not is_exactly_a(expo_)) return power(base_, expo_); using POW = class power; const add& base = ex_to(base_); const numeric& expo = ex_to(expo_); numeric icont = base.integer_content(); const numeric lcoeff = ex_to(base.lead_coeff()).div(icont); if (icont.is_one() or icont.is_minus_one() or not lcoeff.is_integer()) return (new POW(base, expo))-> setflag(status_flags::dynallocated | status_flags::evaluated); ex c; if (expo.is_integer()) { c = icont.pow_intexp(expo.to_long()); } else { bool ppower_equals_one; numeric newbasis, ppower; rational_power_parts(icont, expo, ppower, newbasis, ppower_equals_one); if (ppower_equals_one) { c = POW(icont.abs(), expo).hold(); } else if (icont.is_negative()) c = ppower * POW(-newbasis, expo).hold(); else c = ppower * POW(newbasis, expo).hold(); } auto addp = new add(base); addp->setflag(status_flags::dynallocated); addp->clearflag(status_flags::hash_calculated); addp->overall_coeff /= icont.abs(); addp->seq_sorted.resize(0); for (auto &elem : addp->seq) elem.coeff = ex_to(elem.coeff).div_dyn(icont.abs()); if (likely(not c.is_one())) return (new mul(POW(*addp, expo), c))-> setflag(status_flags::dynallocated | status_flags::evaluated); return (new POW(*addp, expo))-> setflag(status_flags::dynallocated | status_flags::evaluated); } ex add::expand(unsigned options) const { std::unique_ptr vp = expandchildren(options); if (vp == nullptr) { // the terms have not changed, so it is safe to declare this expanded return (options == 0) ? setflag(status_flags::expanded) : *this; } return (new add(*vp, overall_coeff))->setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)); } const epvector & add::get_sorted_seq() const { if (seq_sorted.empty() and not seq.empty()) { seq_sorted = epvector(seq.size()); partial_sort_copy(seq.begin(), seq.end(), seq_sorted.begin(), seq_sorted.end(), print_order_pair()); } return expairseq::get_sorted_seq(); } ex add::lead_coeff() const { // if sorted_seq was computed before, we don't have to search if (seq_sorted.empty() and not seq.empty()) { return min_element(seq.begin(), seq.end(), print_order_pair())->coeff; } return seq_sorted.begin()->coeff; } ex add::combine_fractions() const { epvector rseq; exmap fmap; ex oc = overall_coeff; for (const auto& pair : seq) { using POW = class power; const ex &e = recombine_pair_to_ex(pair); if (is_exactly_a(e)) { const POW& p = ex_to(e); const ex& eexp = p.op(1); if (eexp.info(info_flags::negative)) { auto it = fmap.find(p); if (it != fmap.end()) it->second += _ex1; else fmap[p] = _ex1; } else rseq.push_back(pair); } else if (is_exactly_a(e)) { const mul& m = ex_to(e); epvector denseq, coseq; for (const auto& mpair : m.seq) { if (mpair.coeff.info(info_flags::negative)) denseq.push_back(mpair); else coseq.push_back(mpair); } if (not denseq.empty()) { mul den(denseq); auto it = fmap.find(den); mul tcoeff(coseq, ex_to(pair.coeff)); if (it != fmap.end()) { it->second += tcoeff; } else fmap[den] = tcoeff; } else rseq.push_back(pair); } else rseq.push_back(pair); } for (const auto& t : fmap) rseq.push_back(split_ex_to_pair(mul(t.first, t.second))); add rex(rseq); return add(rex, oc); } } // namespace GiNaC pynac-pynac-0.7.29/ginac/add.h000066400000000000000000000076141406646613100160340ustar00rootroot00000000000000/** @file add.h * * Interface to GiNaC's sums of expressions. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GINAC_ADD_H__ #define __GINAC_ADD_H__ #include "expairseq.h" namespace GiNaC { /** Sum of expressions. */ class add : public expairseq { GINAC_DECLARE_REGISTERED_CLASS(add, expairseq) friend class ex; friend class mul; friend class power; friend ex Power(const ex& base_, const ex& expo_); // other constructors public: add(const ex & lh, const ex & rh); add(const exvector & v, bool hold=false); add(const epvector & v); add(const epvector & v, const numeric & oc); // add(std::unique_ptr vp, const ex & oc); static ex unarchive(const archive_node &n, lst &sym_lst) { return (new add(n, sym_lst))-> setflag(status_flags::dynallocated); } // functions overriding virtual functions from base classes public: unsigned precedence() const override {return 40;} bool info(unsigned inf) const override; bool is_polynomial(const ex & var) const override; numeric degree(const ex & s) const override; numeric ldegree(const ex & s) const override; ex coeff(const ex & s, const ex & n) const override; ex eval(int level=0) const override; ex series(const relational & r, int order, unsigned options = 0) const override; void useries(flint_series_t& fp, int order) const override; ex normal(exmap & repl, exmap & rev_lookup, int level=0, unsigned options = 0) const override; numeric integer_content() const override; ex smod(const numeric &xi) const override; numeric max_coefficient() const override; ex conjugate() const override; ex real_part() const override; ex imag_part() const override; const epvector & get_sorted_seq() const override; ex lead_coeff() const; protected: ex derivative(const symbol & s) const override; unsigned return_type() const override; tinfo_t return_type_tinfo() const override; ex thisexpairseq(const epvector & v, const numeric & oc, bool do_index_renaming = false) const override; ex thisexpairseq(std::unique_ptr vp, const numeric & oc, bool do_index_renaming = false) const override; expair split_ex_to_pair(const ex & e) const override; expair combine_ex_with_coeff_to_pair(const ex & e, const numeric & c) const override; expair combine_pair_with_coeff_to_pair(const expair & p, const numeric & c) const override; ex recombine_pair_to_ex(const expair & p) const override; ex power(const numeric& expo) const; ex expand(unsigned options=0) const override; ex eval_infinity(epvector::const_iterator infinity_iter) const; // non-virtual functions in this class protected: void print_add(const print_context & c, unsigned level, bool latex) const; void do_print(const print_context & c, unsigned level) const override; void do_print_latex(const print_latex & c, unsigned level) const; void do_print_python_repr(const print_python_repr & c, unsigned level) const override; public: ex combine_fractions() const; }; ex Power(const ex& base_, const ex& expo_); } // namespace GiNaC #endif // ndef __GINAC_ADD_H__ pynac-pynac-0.7.29/ginac/archive.cpp000066400000000000000000000426171406646613100172620ustar00rootroot00000000000000/** @file archive.cpp * * Archiving of GiNaC expressions. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "archive.h" #include "registrar.h" #include "ex.h" #include "lst.h" #include "symbol.h" #include "lst.h" #include "container.h" #include "numeric.h" #include "constant.h" #include "function.h" #include "fderivative.h" #include "matrix.h" #include "pseries.h" #include "add.h" #include "mul.h" #include "power.h" #include "infinity.h" #include "exprseq.h" #include "relational.h" #include "pynac-config.h" #include "tostring.h" #include #include #include namespace GiNaC { void archive::archive_ex(const ex &e, const char *name) { // Create root node (which recursively archives the whole expression tree) // and add it to the archive archive_node_id id = add_node(archive_node(*this, e)); // Add root node ID to list of archived expressions archived_ex ae = archived_ex(atomize(name), id); exprs.push_back(ae); } /** Add archive_node to archive if the corresponding expression is * not already archived. * @return ID of archived node */ archive_node_id archive::add_node(const archive_node &n) { // Look if expression is known to be in some node already. if (n.has_ex()) { auto i = exprtable.find(n.get_ex()); if (i != exprtable.end()) return i->second; nodes.push_back(n); exprtable[n.get_ex()] = nodes.size() - 1; return nodes.size() - 1; } // Not found, add archive_node to nodes vector nodes.push_back(n); return nodes.size()-1; } /** Retrieve archive_node by ID. */ archive_node &archive::get_node(archive_node_id id) { if (id >= nodes.size()) throw (std::range_error("archive::get_node(): archive node ID out of range")); return nodes[id]; } ex archive::unarchive_ex(const lst &sym_lst, const char *name) const { // Find root node std::string name_string = name; archive_atom id = atomize(name_string); for (const auto & elem : exprs) { if (elem.name == id) { // Recursively unarchive all nodes, starting at the root node lst sym_lst_copy = sym_lst; return nodes[elem.root].unarchive(sym_lst_copy); } } throw (std::runtime_error("expression with name '" + name_string + "' not found in archive")); } ex archive::unarchive_ex(const lst &sym_lst, unsigned index) const { if (index >= exprs.size()) throw (std::range_error("index of archived expression out of range")); // Recursively unarchive all nodes, starting at the root node lst sym_lst_copy = sym_lst; return nodes[exprs[index].root].unarchive(sym_lst_copy); } ex archive::unarchive_ex(const lst &sym_lst, std::string &name, unsigned index) const { if (index >= exprs.size()) throw (std::range_error("index of archived expression out of range")); // Return expression name name = unatomize(exprs[index].name); // Recursively unarchive all nodes, starting at the root node lst sym_lst_copy = sym_lst; return nodes[exprs[index].root].unarchive(sym_lst_copy); } unsigned archive::num_expressions() const { return exprs.size(); } const archive_node &archive::get_top_node(unsigned index) const { if (index >= exprs.size()) throw (std::range_error("index of archived expression out of range")); return nodes[exprs[index].root]; } /* * Archive file format * * - 4 bytes signature 'GARC' * - unsigned version number * - unsigned number of atoms * - atom strings (each zero-terminated) * - unsigned number of expressions * - unsigned name atom * - unsigned root node ID * - unsigned number of nodes * - unsigned number of properties * - unsigned containing type (PTYPE_*) in its lower 3 bits and * name atom in the upper bits * - unsigned property value * * Unsigned quantities are stored in a compressed format: * - numbers in the range 0x00..0x7f are stored verbatim (1 byte) * - numbers larger than 0x7f are stored in 7-bit packets (1 byte per * packet), starting with the LSBs; all bytes except the last one have * their upper bit set * * Examples: * 0x00 = 0x00 * .. .. * 0x7f = 0x7f * 0x80 0x01 = 0x80 * .. .. .. * 0xff 0x01 = 0xff * 0x80 0x02 = 0x100 * .. .. .. * 0xff 0x02 = 0x17f * 0x80 0x03 = 0x180 * .. .. .. * 0xff 0x7f = 0x3fff * 0x80 0x80 0x01 = 0x4000 * .. .. .. .. */ /** Write unsigned integer quantity to stream. */ static void write_unsigned(std::ostream &os, unsigned val) { while (val >= 0x80) { os.put((val & 0x7f) | 0x80); val >>= 7; } os.put(val); } /** Read unsigned integer quantity from stream. */ static unsigned read_unsigned(std::istream &is) { unsigned char b = 0; unsigned ret = 0; unsigned shift = 0; do { char b2 = 0; if (is.get(b2)) b = b2; ret |= (b & 0x7f) << shift; shift += 7; } while ((b & 0x80) != 0); return ret; } /** Write archive_node to binary data stream. */ std::ostream &operator<<(std::ostream &os, const archive_node &n) { // Write properties unsigned num_props = n.props.size(); write_unsigned(os, num_props); for (unsigned i=0; i>(std::istream &is, archive_node &n) { // Read properties unsigned num_props = read_unsigned(is); n.props.resize(num_props); for (unsigned i=0; i(name_type & 7); n.props[i].name = name_type >> 3; n.props[i].value = read_unsigned(is); } return is; } /** Read archive from binary data stream. */ std::istream &operator>>(std::istream &is, archive &ar) { // Read header char c1 = 0, c2 = 0, c3 = 0, c4 = 0; is.get(c1); is.get(c2); is.get(c3); is.get(c4); if (c1 != 'G' || c2 != 'A' || c3 != 'R' || c4 != 'C') throw (std::runtime_error("not a GiNaC archive (signature not found)")); unsigned version = read_unsigned(is); if (version > PYNAC_ARCHIVE_VERSION || version < PYNAC_ARCHIVE_VERSION - PYNAC_ARCHIVE_AGE) throw (std::runtime_error("archive version " + ToString(version) + " cannot be read by this GiNaC library (which supports versions " + ToString(PYNAC_ARCHIVE_VERSION-PYNAC_ARCHIVE_AGE) + " thru " + ToString(PYNAC_ARCHIVE_VERSION))); // Read atoms unsigned num_atoms = read_unsigned(is); ar.atoms.resize(num_atoms); for (unsigned i=0; i> ar.nodes[i]; return is; } /** Atomize a string (i.e. convert it into an ID number that uniquely * represents the string). */ archive_atom archive::atomize(const std::string &s) const { // Search for string in inverse_atoms map. inv_at_cit i = inverse_atoms.find(s); if (i!=inverse_atoms.end()) return i->second; // Not found, add to atoms vector archive_atom id = atoms.size(); atoms.push_back(s); inverse_atoms[s] = id; return id; } /** Unatomize a string (i.e. convert the ID number back to the string). */ const std::string &archive::unatomize(archive_atom id) const { if (id >= atoms.size()) throw (std::range_error("archive::unatomizee(): atom ID out of range")); return atoms[id]; } /** Assignment operator of archive_node. */ const archive_node &archive_node::operator=(const archive_node &other) { if (this != &other) { // archive &a member doesn't get copied props = other.props; has_expression = other.has_expression; e = other.e; } return *this; } /** Recursively construct archive node from expression. */ archive_node::archive_node(archive &ar, const ex &expr) : a(ar), has_expression(true), e(expr) { expr.bp->archive(*this); } /** Check if the archive_node stores the same expression as another * archive_node. * @return "true" if expressions are the same */ bool archive_node::has_same_ex_as(const archive_node &other) const { if (!has_expression || !other.has_expression) return false; return e.bp == other.e.bp; } archive_node::archive_node_cit archive_node::find_first(const std::string &name) const { archive_atom name_atom = a.atomize(name); for (auto i=props.begin(); i!=props.end(); ++i) if (i->name == name_atom) return i; return props.end();; } archive_node::archive_node_cit archive_node::find_last(const std::string &name) const { archive_atom name_atom = a.atomize(name); for (auto i=props.end(); i!=props.begin();) { --i; if (i->name == name_atom) return i; } return props.end(); } void archive_node::add_bool(const std::string &name, bool value) { props.emplace_back(a.atomize(name), PTYPE_BOOL, static_cast(value)); } void archive_node::add_unsigned(const std::string &name, unsigned value) { props.emplace_back(a.atomize(name), PTYPE_UNSIGNED, value); } void archive_node::add_string(const std::string &name, const std::string &value) { props.emplace_back(a.atomize(name), PTYPE_STRING, a.atomize(value)); } void archive_node::add_ex(const std::string &name, const ex &value) { // Recursively create an archive_node and add its ID to the properties of this node archive_node_id id = a.add_node(archive_node(a, value)); props.emplace_back(a.atomize(name), PTYPE_NODE, id); } bool archive_node::find_bool(const std::string &name, bool &ret, unsigned index) const { archive_atom name_atom = a.atomize(name); unsigned found_index = 0; for (const auto & elem : props) { if (elem.type == PTYPE_BOOL && elem.name == name_atom) { if (found_index == index) { ret = (elem.value != 0u); return true; } found_index++; } } return false; } bool archive_node::find_unsigned(const std::string &name, unsigned &ret, unsigned index) const { archive_atom name_atom = a.atomize(name); unsigned found_index = 0; for (const auto & elem : props) { if (elem.type == PTYPE_UNSIGNED && elem.name == name_atom) { if (found_index == index) { ret = elem.value; return true; } found_index++; } } return false; } bool archive_node::find_string(const std::string &name, std::string &ret, unsigned index) const { archive_atom name_atom = a.atomize(name); unsigned found_index = 0; for (const auto & elem : props) { if (elem.type == PTYPE_STRING && elem.name == name_atom) { if (found_index == index) { ret = a.unatomize(elem.value); return true; } found_index++; } } return false; } void archive_node::find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst) const { ret = a.get_node(loc->value).unarchive(sym_lst); } bool archive_node::find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index) const { archive_atom name_atom = a.atomize(name); unsigned found_index = 0; for (const auto & elem : props) { if (elem.type == PTYPE_NODE && elem.name == name_atom) { if (found_index == index) { ret = a.get_node(elem.value).unarchive(sym_lst); return true; } found_index++; } } return false; } const archive_node &archive_node::find_ex_node(const std::string &name, unsigned index) const { archive_atom name_atom = a.atomize(name); unsigned found_index = 0; for (const auto & elem : props) { if (elem.type == PTYPE_NODE && elem.name == name_atom) { if (found_index == index) return a.get_node(elem.value); found_index++; } } throw (std::runtime_error("property with name '" + name + "' not found in archive node")); } void archive_node::get_properties(propinfovector &v) const { v.clear(); for (const auto & elem : props) { property_type type = elem.type; std::string name = a.unatomize(elem.name); bool found = false; for (auto & velem : v) { if (velem.type == type && velem.name == name) { velem.count++; found = true; break; } } if (!found) v.emplace_back(type, name); } } using unarch_func_t = ex (*)(const archive_node&, lst&); using unarch_func_map = std::unordered_map; static unarch_func_map& fill_map() { static unarch_func_map map; map["symbol"] = symbol::unarchive; map["lst"] = lst::unarchive; map["numeric"] = numeric::unarchive; map["constant"] = constant::unarchive; map["function"] = function::unarchive; map["fderivative"] = fderivative::unarchive; map["matrix"] = matrix::unarchive; map["pseries"] = pseries::unarchive; map["add"] = add::unarchive; map["mul"] = mul::unarchive; map["power"] = power::unarchive; map["infinity"] = infinity::unarchive; map["exprseq"] = exprseq::unarchive; map["relational"] = relational::unarchive; return map; } static const unarch_func_t& find_unarch_func(const std::string& s) { static unarch_func_map& map = fill_map(); auto it = map.find(s); if (it == map.end()) throw std::runtime_error("can't happen"); return it->second; } /** Convert archive node to GiNaC expression. */ ex archive_node::unarchive(lst &sym_lst) const { // Already unarchived? Then return cached unarchived expression. if (has_expression) return e; // Find instantiation function for class specified in node std::string class_name; if (!find_string("class", class_name)) throw (std::runtime_error("archive node contains no class name")); const unarch_func_t f = find_unarch_func(class_name); // Call instantiation function e = f(*this, sym_lst); has_expression = true; return ex(e); } void archive::clear() { atoms.clear(); inverse_atoms.clear(); exprs.clear(); nodes.clear(); exprtable.clear(); } /** Delete cached unarchived expressions in all archive_nodes (mainly for debugging). */ void archive::forget() { for_each(nodes.begin(), nodes.end(), std::mem_fun_ref(&archive_node::forget)); } /** Delete cached unarchived expressions from node (for debugging). */ void archive_node::forget() { has_expression = false; e = 0; } /** Print archive to stream in ugly raw format (for debugging). */ void archive::printraw(std::ostream &os) const { // Dump atoms os << "Atoms:\n"; { archive_atom id = 0; for (const auto & elem : atoms) { os << " " << id << " " << elem << std::endl; id++; } } os << std::endl; // Dump expressions os << "Expressions:\n"; { unsigned index = 0; for (const auto & elem : exprs) { os << " " << index << " \"" << unatomize(elem.name) << "\" root node " << elem.root << std::endl; index++; } } os << std::endl; // Dump nodes os << "Nodes:\n"; { archive_node_id id = 0; for (const auto & elem : nodes) { os << " " << id << " "; elem.printraw(os); id++; } } } /** Output archive_node to stream in ugly raw format (for debugging). */ void archive_node::printraw(std::ostream &os) const { // Dump cached unarchived expression if (has_expression) os << "(basic * " << e.bp << " = " << e << ")\n"; else os << "\n"; // Dump properties for (const auto & elem : props) { os << " "; switch (elem.type) { case PTYPE_BOOL: os << "bool"; break; case PTYPE_UNSIGNED: os << "unsigned"; break; case PTYPE_STRING: os << "string"; break; case PTYPE_NODE: os << "node"; break; default: os << ""; break; } os << " \"" << a.unatomize(elem.name) << "\" " << elem.value << std::endl; } } /** Create a dummy archive. The intention is to fill archive_node's default * ctor, which is currently a Cint-requirement. */ archive* archive_node::dummy_ar_creator() { static auto some_ar = new archive; return some_ar; } } // namespace GiNaC pynac-pynac-0.7.29/ginac/archive.h000066400000000000000000000214561406646613100167250ustar00rootroot00000000000000/** @file archive.h * * Archiving of GiNaC expressions. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GINAC_ARCHIVE_H__ #define __GINAC_ARCHIVE_H__ #include "ex.h" #include #include #include #include namespace GiNaC { class archive; /** Numerical ID value to refer to an archive_node. */ typedef unsigned archive_node_id; /** Numerical ID value to refer to a string. */ typedef unsigned archive_atom; /** This class stores all properties needed to record/retrieve the state * of one object of class basic (or a derived class). Each property is * addressed by its name and data type. */ class archive_node { friend std::ostream &operator<<(std::ostream &os, const archive_node &ar); friend std::istream &operator>>(std::istream &is, archive_node &ar); public: /** Property data types */ enum property_type { PTYPE_BOOL, PTYPE_UNSIGNED, PTYPE_STRING, PTYPE_NODE }; /** Information about a stored property. A vector of these structures * is returned by get_properties(). * @see get_properties */ struct property_info { property_info() {} property_info(property_type t, std::string n, unsigned c = 1) : type(t), name(std::move(n)), count(c) {} property_type type; /**< Data type of property. */ std::string name; /**< Name of property. */ unsigned count; /**< Number of occurrences. */ }; typedef std::vector propinfovector; /** Archived property (data type, name and associated data) */ struct property { property() {} property(archive_atom n, property_type t, unsigned v) : type(t), name(n), value(v) {} property_type type; /**< Data type of property. */ archive_atom name; /**< Name of property. */ unsigned value; /**< Stored value. */ }; typedef std::vector::const_iterator archive_node_cit; archive_node() : a(*dummy_ar_creator()), has_expression(false) {} // hack for cint which always requires a default constructor archive_node(archive &ar) : a(ar), has_expression(false) {} archive_node(archive &ar, const ex &expr); const archive_node &operator=(const archive_node &other); /** Add property of type "bool" to node. */ void add_bool(const std::string &name, bool value); /** Add property of type "unsigned int" to node. */ void add_unsigned(const std::string &name, unsigned value); /** Add property of type "string" to node. */ void add_string(const std::string &name, const std::string &value); /** Add property of type "ex" to node. */ void add_ex(const std::string &name, const ex &value); /** Retrieve property of type "bool" from node. * @return "true" if property was found, "false" otherwise */ bool find_bool(const std::string &name, bool &ret, unsigned index = 0) const; /** Retrieve property of type "unsigned" from node. * @return "true" if property was found, "false" otherwise */ bool find_unsigned(const std::string &name, unsigned &ret, unsigned index = 0) const; /** Retrieve property of type "string" from node. * @return "true" if property was found, "false" otherwise */ bool find_string(const std::string &name, std::string &ret, unsigned index = 0) const; /** Find the location in the vector of properties of the first/last * property with a given name. */ archive_node_cit find_first(const std::string &name) const; archive_node_cit find_last(const std::string &name) const; /** Retrieve property of type "ex" from node. * @return "true" if property was found, "false" otherwise */ bool find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index = 0) const; /** Retrieve property of type "ex" from the node if it is known * that this node in fact contains such a property at the given * location. This is much more efficient than the preceding function. */ void find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst) const; /** Retrieve property of type "ex" from node, returning the node of * the sub-expression. */ const archive_node &find_ex_node(const std::string &name, unsigned index = 0) const; /** Return vector of properties stored in node. */ void get_properties(propinfovector &v) const; ex unarchive(lst &sym_lst) const; bool has_same_ex_as(const archive_node &other) const; bool has_ex() const {return has_expression;} ex get_ex() const {return e;} void forget(); void printraw(std::ostream &os) const; private: static archive* dummy_ar_creator(); /** Reference to the archive to which this node belongs. */ archive &a; /** Vector of stored properties. */ std::vector props; /** Flag indicating whether a cached unarchived representation of this node exists. */ mutable bool has_expression; /** The cached unarchived representation of this node (if any). */ mutable ex e; }; /** This class holds archived versions of GiNaC expressions (class ex). * An archive can be constructed from an expression and then written to * a stream; or it can be read from a stream and then unarchived, yielding * back the expression. Archives can hold multiple expressions which can * be referred to by name or index number. The main component of the * archive class is a vector of archive_nodes which each store one object * of class basic (or a derived class). */ class archive { friend std::ostream &operator<<(std::ostream &os, const archive &ar); friend std::istream &operator>>(std::istream &is, archive &ar); public: archive() {} ~archive() {} /** Construct archive from expression using the default name "ex". */ archive(const ex &e) {archive_ex(e, "ex");} /** Construct archive from expression using the specified name. */ archive(const ex &e, const char *n) {archive_ex(e, n);} /** Archive an expression. * @param e the expression to be archived * @param name name under which the expression is stored */ void archive_ex(const ex &e, const char *name); /** Retrieve expression from archive by name. * @param sym_lst list of pre-defined symbols * @param name name of expression */ ex unarchive_ex(const lst &sym_lst, const char *name) const; /** Retrieve expression from archive by index. * @param sym_lst list of pre-defined symbols * @param index index of expression * @see count_expressions */ ex unarchive_ex(const lst &sym_lst, unsigned index = 0) const; /** Retrieve expression and its name from archive by index. * @param sym_lst list of pre-defined symbols * @param name receives the name of the expression * @param index index of expression * @see count_expressions */ ex unarchive_ex(const lst &sym_lst, std::string &name, unsigned index = 0) const; /** Return number of archived expressions. */ unsigned num_expressions() const; /** Return reference to top node of an expression specified by index. */ const archive_node &get_top_node(unsigned index = 0) const; /** Clear all archived expressions. */ void clear(); archive_node_id add_node(const archive_node &n); archive_node &get_node(archive_node_id id); void forget(); void printraw(std::ostream &os) const; private: /** Vector of archived nodes. */ std::vector nodes; /** Archived expression descriptor. */ struct archived_ex { archived_ex() {} archived_ex(archive_atom n, archive_node_id node) : name(n), root(node) {} archive_atom name; /**< Name of expression. */ archive_node_id root; /**< ID of root node. */ }; /** Vector of archived expression descriptors. */ std::vector exprs; public: archive_atom atomize(const std::string &s) const; const std::string &unatomize(archive_atom id) const; private: /** Vector of atomized strings (using a vector allows faster unarchiving). */ mutable std::vector atoms; /** The map of from strings to indices of the atoms vectors allows for * faster archiving. */ typedef std::map::const_iterator inv_at_cit; mutable std::map inverse_atoms; /** Map of stored expressions to nodes for faster archiving */ typedef std::map::iterator mapit; mutable std::map exprtable; }; } // namespace GiNaC #endif // ndef __GINAC_ARCHIVE_H__ pynac-pynac-0.7.29/ginac/assertion.h000066400000000000000000000023301406646613100173010ustar00rootroot00000000000000/** @file assertion.h * * Assertion macro definition. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GINAC_ASSERTION_H__ #define __GINAC_ASSERTION_H__ #if !defined(GINAC_ASSERT) #if defined(DO_GINAC_ASSERT) #include /** Assertion macro for checking invariances. */ #define GINAC_ASSERT(X) assert(X) #else /** Assertion macro for checking invariances. */ #define GINAC_ASSERT(X) ((void)0) #endif #endif #endif // ndef __GINAC_ASSERTION_H__ pynac-pynac-0.7.29/ginac/assume.cpp000066400000000000000000000032601406646613100171250ustar00rootroot00000000000000/* * File: assume.cpp * Author: Ralf Stephan * * Created on August 5, 2015, 9:31 AM */ #include "ex.h" #include "operators.h" #include "symbol.h" #include "function.h" #include "relational.h" #include "utils.h" #include "flags.h" #include "infoflagbase.h" namespace GiNaC { void assume(ex rel) { // It was already checked that rel is a relational. const relational& r = ex_to(rel); if (r.the_operator() == relational::equal or r.the_operator() == relational::not_equal) return; ex df = (r.lhs() - r.rhs()).expand(); if (r.the_operator() == relational::greater) df.set_domain(domain::positive); if (r.the_operator() == relational::less) df.set_domain(domain::negative); } void assume(ex x, char* flag_desc) { if (strcmp(flag_desc, "integer") == 0) x.set_domain(domain::integer); else if (strcmp(flag_desc, "real") == 0) x.set_domain(domain::real); else if (strcmp(flag_desc, "complex") == 0) x.set_domain(domain::complex); else if (strcmp(flag_desc, "even") == 0) x.set_domain(domain::even); } void forget(ex rel) { // It was already checked that rel is a relational. const relational& r = ex_to(rel); if (r.the_operator() == relational::equal or r.the_operator() == relational::not_equal) return; ex df = (r.lhs() - r.rhs()).expand(); df.set_domain(domain::complex); } void forget(ex x, char* flag_desc) { x.set_domain(domain::complex); } } // namespace GiNaC pynac-pynac-0.7.29/ginac/assume.h000066400000000000000000000005371406646613100165760ustar00rootroot00000000000000/* * File: assume.h * Author: Ralf Stephan * * Created on August 5, 2015, 7:22 AM */ #ifndef ASSUME_H #define ASSUME_H #include namespace GiNaC { void assume(ex rel); void assume(ex x, char* flag_desc); void forget(ex rel); void forget(ex x, char* flag_desc); } // namespace GiNaC #endif /* ASSUME_H */ pynac-pynac-0.7.29/ginac/basic.cpp000066400000000000000000000661021406646613100167150ustar00rootroot00000000000000/** @file basic.cpp * * Implementation of GiNaC's ABC. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "basic.h" #include "ex.h" #include "expairseq.h" #include "ex_utils.h" #include "numeric.h" #include "power.h" #include "add.h" #include "symbol.h" #include "lst.h" #include "relational.h" #include "operators.h" #include "wildcard.h" #include "archive.h" #include "utils.h" #include "inifcns.h" #include #include #ifdef DO_GINAC_ASSERT # include #endif namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(basic, void, print_func(&basic::do_print). print_func(&basic::do_print_tree). print_func(&basic::do_print_python_repr)) ////////// // default constructor, destructor, copy constructor and assignment operator ////////// // public /** basic copy constructor: implicitly assumes that the other class is of * the exact same type (as it's used by duplicate()), so it can copy the * tinfo_key and the hash value. */ basic::basic(const basic & other) : tinfo_key(other.tinfo_key), flags(other.flags & ~status_flags::dynallocated), hashvalue(other.hashvalue) { } /** basic assignment operator: the other object might be of a derived class. */ const basic & basic::operator=(const basic & other) { unsigned fl = other.flags & ~status_flags::dynallocated; if (tinfo_key != other.tinfo_key) { // The other object is of a derived class, so clear the flags as they // might no longer apply (especially hash_calculated). Oh, and don't // copy the tinfo_key: it is already set correctly for this object. fl &= ~(status_flags::evaluated | status_flags::expanded | status_flags::hash_calculated); } else { // The objects are of the exact same class, so copy the hash value. hashvalue = other.hashvalue; } flags = fl; set_refcount(0); return *this; } // protected // none (all inlined) ////////// // other constructors ////////// // none (all inlined) ////////// // archiving ////////// /** Construct object from archive_node. */ basic::basic(const archive_node &n, lst& /*unused*/) : flags(0) { // Reconstruct tinfo_key from class name std::string found_class_name; if (n.find_string("class", found_class_name)) tinfo_key = find_tinfo_key(found_class_name); else throw (std::runtime_error("archive node contains no class name")); } /** Archive the object. */ void basic::archive(archive_node &n) const { n.add_string("class", class_name()); } ////////// // new virtual functions which can be overridden by derived classes ////////// // public /** Output to stream. This performs double dispatch on the dynamic type of * *this and the dynamic type of the supplied print context. * @param c print context object that describes the output formatting * @param level value that is used to identify the precedence or indentation * level for placing parentheses and formatting */ void basic::print(const print_context & c, unsigned level) const { print_dispatch(get_class_info(), c, level); } /** Like print(), but dispatch to the specified class. Can be used by * implementations of print methods to dispatch to the method of the * superclass. * * @see basic::print */ void basic::print_dispatch(const registered_class_info & ri, const print_context & c, unsigned level) const { // Double dispatch on object type and print_context type const registered_class_info * r_info = &ri; const print_context_class_info * pc_info = &c.get_class_info(); const std::vector * pdt = &r_info->options.get_print_dispatch_table(); unsigned id = pc_info->options.get_id(); while(id >= pdt->size() or not ((*pdt)[id].is_valid())) { // Method not found, try parent print_context class const print_context_class_info * parent_pc_info = pc_info->get_parent(); if (parent_pc_info != nullptr) { pc_info = parent_pc_info; id = pc_info->options.get_id(); continue; } // Method still not found, try parent class const registered_class_info * parent_reg_info = r_info->get_parent(); if (parent_reg_info != nullptr) { r_info = parent_reg_info; pc_info = &c.get_class_info(); pdt = &r_info->options.get_print_dispatch_table(); id = pc_info->options.get_id(); continue; } // Method still not found. This shouldn't happen because basic (the // base class of the algebraic hierarchy) registers a method for // print_context (the base class of the print context hierarchy), // so if we end up here, there's something wrong with the class // registry. throw (std::runtime_error(std::string("basic::print(): method for ") + class_name() + "/" + c.class_name() + " not found")); } // Call method (*pdt)[id](*this, c, level); } /** Default output to stream. */ void basic::do_print(const print_context & c, unsigned /*unused*/) const { c.s << "[" << class_name() << " object]"; } /** Tree output to stream. */ void basic::do_print_tree(const print_tree & c, unsigned level) const { c.s << std::string(level, ' ') << class_name() << " @" << this << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec; if (nops() != 0u) c.s << ", nops=" << nops(); c.s << std::endl; for (size_t i=0; iprint(print_dflt(std::cerr)); std::cerr << std::endl; } /** Little wrapper around printtree to be called within a debugger. * * @see basic::dbgprint */ void basic::dbgprinttree() const { this->print(print_tree(std::cerr)); } /** Return relative operator precedence (for parenthezing output). */ unsigned basic::precedence() const { return 70; } /** Information about the object. * * @see class info_flags */ bool basic::info(unsigned /*unused*/) const { // all possible properties are false for basic objects return false; } /** Number of operands/members. */ size_t basic::nops() const { // iterating from 0 to nops() on atomic objects should be an empty loop, // and accessing their elements is a range error. Container objects should // override this. return 0; } /** Return operand/member at position i. */ const ex basic::op(size_t /*unused*/) const { throw(std::range_error(std::string("basic::op(): ") + class_name() + std::string(" has no operands"))); } /** Return modifiable operand/member at position i. */ ex & basic::let_op(size_t /*unused*/) { ensure_if_modifiable(); throw(std::range_error(std::string("basic::let_op(): ") + class_name() + std::string(" has no operands"))); } ex basic::operator[](const ex & index) const { if (is_exactly_a(index)) return op(static_cast(ex_to(index).to_int())); throw(std::invalid_argument(std::string("non-numeric indices not supported by ") + class_name())); } ex basic::operator[](size_t i) const { return op(i); } ex & basic::operator[](const ex & index) { if (is_exactly_a(index)) return let_op(ex_to(index).to_int()); throw(std::invalid_argument(std::string("non-numeric indices not supported by ") + class_name())); } ex & basic::operator[](size_t i) { return let_op(i); } void basic::set_epseq_from(size_t i, ex e) { dynamic_cast(*this).set_pair_from(i, e); } /** Test for occurrence of a pattern. An object 'has' a pattern if it matches * the pattern itself or one of the children 'has' it. As a consequence * (according to the definition of children) given e=x+y+z, e.has(x) is true * but e.has(x+y) is false. */ bool basic::has(const ex & pattern, unsigned options) const { exmap map; if (match(pattern, map)) return true; for (size_t i=0; ilet_op(i) = n; } } if (copy == nullptr) return *this; copy->setflag(status_flags::dynallocated); copy->clearflag(status_flags::hash_calculated | status_flags::expanded); return *copy; } /** Check whether this is a polynomial in the given variables. */ bool basic::is_polynomial(const ex & var) const { return !has(var) || is_equal(ex_to(var)); } /** Return degree of highest power in object s. */ numeric basic::degree(const ex & s) const { return is_equal(ex_to(s)) ? *_num1_p : *_num0_p; } /** Return degree of lowest power in object s. */ numeric basic::ldegree(const ex & s) const { return is_equal(ex_to(s)) ? *_num1_p : *_num0_p; } /** Return coefficient of degree n in object s. */ ex basic::coeff(const ex & s, const ex & n) const { if (is_equal(ex_to(s))) return n.is_one() ? _ex1 : _ex0; return n.is_zero() ? *this : _ex0; } /** Sort expanded expression in terms of powers of some object(s). * @param s object(s) to sort in * @param distributed recursive or distributed form (only used when s is a list) */ ex basic::collect(const ex & s, bool distributed) const { ex x; if (is_exactly_a(s)) { // List of objects specified if (s.nops() == 0) return *this; if (s.nops() == 1) return collect(s.op(0)); if (distributed) { x = this->expand(); if (! is_exactly_a(x)) return x; const lst& l(ex_to(s)); exmap cmap; cmap[_ex1] = _ex0; for (const auto & xelem : x) { ex key = _ex1; ex pre_coeff = xelem; for (const auto & lelem : l) { ex cexp = pre_coeff.degree(lelem); pre_coeff = pre_coeff.coeff(lelem, cexp); key *= pow(lelem, cexp); } auto ci = cmap.find(key); if (ci != cmap.end()) ci->second += pre_coeff; else cmap.insert(exmap::value_type(key, pre_coeff)); } exvector resv; for (const auto & elem : cmap) resv.push_back((elem.first) * (elem.second)); return (new add(resv))->setflag(status_flags::dynallocated); } else { // Recursive form x = *this; size_t n = s.nops() - 1; while (true) { x = x.collect(s[n]); if (n == 0) break; n--; } } } else { // Only one object specified expairvec vec; ex(*this).coefficients(s, vec); for (const auto& term : vec) x += term.first * power(s, term.second); return x; } // correct for lost fractional arguments and return return x + (*this - x).expand(); } /** Perform automatic non-interruptive term rewriting rules. */ ex basic::eval(int /*unused*/) const { // There is nothing to do for basic objects: return hold(); } /** Function object to be applied by basic::evalf(). */ struct evalf_map_function : public map_function { int level; PyObject* parent; evalf_map_function(int l, PyObject* p) : level(l), parent(p) {} ex operator()(const ex & e) override { return evalf(e, level, parent); } }; /** Evaluate object numerically. */ ex basic::evalf(int level, PyObject* parent) const { if (nops() == 0) return *this; if (level == 1) return *this; if (level == -max_recursion_level) throw(std::runtime_error("max recursion level reached")); evalf_map_function map_evalf(level - 1, parent); return map(map_evalf); } /** Evaluate sums, products and integer powers of matrices. */ ex basic::evalm() const { return *this; } #if 0 /** Perform automatic symbolic evaluations on indexed expression that * contains this object as the base expression. */ ex basic::eval_indexed(const basic & i) const // this function can't take a "const ex & i" because that would result // in an infinite eval() loop { // There is nothing to do for basic objects return i.hold(); } /** Add two indexed expressions. They are guaranteed to be of class indexed * (or a subclass) and their indices are compatible. This function is used * internally by simplify_indexed(). * * @param self First indexed expression; its base object is *this * @param other Second indexed expression * @return sum of self and other * @see ex::simplify_indexed() */ ex basic::add_indexed(const ex & self, const ex & other) const { return self + other; } /** Multiply an indexed expression with a scalar. This function is used * internally by simplify_indexed(). * * @param self Indexed expression; its base object is *this * @param other Numeric value * @return product of self and other * @see ex::simplify_indexed() */ ex basic::scalar_mul_indexed(const ex & self, const numeric & other) const { return self * other; } /** Try to contract two indexed expressions that appear in the same product. * If a contraction exists, the function overwrites one or both of the * expressions and returns true. Otherwise it returns false. It is * guaranteed that both expressions are of class indexed (or a subclass) * and that at least one dummy index has been found. This functions is * used internally by simplify_indexed(). * * @param self Pointer to first indexed expression; its base object is *this * @param other Pointer to second indexed expression * @param v The complete vector of factors * @return true if the contraction was successful, false otherwise * @see ex::simplify_indexed() */ bool basic::contract_with(exvector::iterator /*unused*/, exvector::iterator /*unused*/, exvector& /*unused*/) const { // Do nothing return false; } #endif /** Check whether the expression matches a given pattern. For every wildcard * object in the pattern, an expression of the form "wildcard == matching_expression" * is added to repl_lst. */ bool basic::match(const ex & pattern, exmap& map) const { /* Sweet sweet shapes, sweet sweet shapes, That's the key thing, right right. Feed feed face, feed feed shapes, But who is the king tonight? Who is the king tonight? Pattern is the thing, the key thing-a-ling, But who is the king of Pattern? But who is the king, the king thing-a-ling, Who is the king of Pattern? Bog is the king, the king thing-a-ling, Bog is the king of Pattern. Ba bu-bu-bu-bu bu-bu-bu-bu-bu-bu bu-bu Bog is the king of Pattern. */ if (is_exactly_a(pattern)) { // Wildcard matches anything, but check whether we already have found // a match for that wildcard first (if so, the earlier match must be // the same expression) const auto& it = map.find(pattern); if (it != map.end()) return is_equal(ex_to(it->second)); map[pattern] = *this; return true; } // Expression must be of the same type as the pattern if (tinfo() != ex_to(pattern).tinfo()) return false; // Number of subexpressions must match if (nops() != pattern.nops()) return false; // No subexpressions? Then just compare the objects (there can't be // wildcards in the pattern) if (nops() == 0) return is_equal_same_type(ex_to(pattern)); // Check whether attributes that are not subexpressions match if (!match_same_type(ex_to(pattern))) return false; // Otherwise the subexpressions must match one-to-one for (size_t i=0; i(thisex)) return ex_to(thisex).subs(m, options); for (const auto & pair : m) if (thisex.is_equal(pair.first)) return pair.second; } else { for (const auto & elem : m) { exmap map; if (match(ex_to(elem.first), map)) { lst repl_lst; for (const auto& pair : map) repl_lst.append(pair.first == pair.second); // avoid infinite recursion when // re-substituting the wildcards return elem.second.subs(repl_lst, options | subs_options::no_pattern); } } } return *this; } /** Substitute a set of objects by arbitrary expressions. The ex returned * will already be evaluated. */ ex basic::subs(const exmap & m, unsigned options) const { size_t num = nops(); if (num != 0u) { // Substitute in subexpressions for (size_t i=0; isetflag(status_flags::dynallocated); copy->clearflag(status_flags::hash_calculated | status_flags::expanded); // Substitute the changed operand copy->let_op(i++) = subsed_op; // Substitute the other operands for (; ilet_op(i) = op(i).subs(m, options); // Perform substitutions on the new object as a whole return copy->subs_one_level(m, options); } } } // Nothing changed or no subexpressions return subs_one_level(m, options); } /** Default interface of nth derivative ex::diff(s, n). It should be called * instead of ::derivative(s) for first derivatives and for nth derivatives it * just recurses down. * * @param s symbol to differentiate in * @param nth order of differentiation * @see ex::diff */ ex basic::diff(const symbol & s, unsigned nth) const { // trivial: zeroth derivative if (nth==0) return ex(*this); // evaluate unevaluated *this before differentiating if (not is_evaluated()) return ex(*this).diff(s, nth); ex ndiff = this->derivative(s); while (!ndiff.is_zero() && // stop differentiating zeros nth>1) { ndiff = ndiff.diff(s); --nth; } return ndiff; } ex basic::conjugate() const { return *this; } ex basic::real_part() const { return real_part_function(*this).hold(); } ex basic::imag_part() const { return imag_part_function(*this).hold(); } // protected /** Function object to be applied by basic::derivative(). */ struct derivative_map_function : public map_function { const symbol &s; derivative_map_function(const symbol &sym) : s(sym) {} ex operator()(const ex & e) override { return diff(e, s); } }; /** Default implementation of ex::diff(). It maps the operation on the * operands (or returns 0 when the object has no operands). * * @see ex::diff */ ex basic::derivative(const symbol & s) const { if (nops() == 0) return _ex0; derivative_map_function map_derivative(s); return map(map_derivative); } /** Returns order relation between two objects of same type. This needs to be * implemented by each class. It may never return anything else than 0, * signalling equality, or +1 and -1 signalling inequality and determining * the canonical ordering. (Perl hackers will wonder why C++ doesn't feature * the spaceship operator <=> for denoting just this.) */ int basic::compare_same_type(const basic & other) const { return compare_pointers(this, &other); } /** Returns true if two objects of same type are equal. Normally needs * not be reimplemented as long as it wasn't overwritten by some parent * class, since it just calls compare_same_type(). The reason why this * function exists is that sometimes it is easier to determine equality * than an order relation and then it can be overridden. */ bool basic::is_equal_same_type(const basic & other) const { return compare_same_type(other)==0; } /** Returns true if the attributes of two objects are similar enough for * a match. This function must not match subexpressions (this is already * done by basic::match()). Only attributes not accessible by op() should * be compared. This is also the reason why this function doesn't take the * wildcard replacement list from match() as an argument: only subexpressions * are subject to wildcard matches. Also, this function only needs to be * implemented for container classes because is_equal_same_type() is * automatically used instead of match_same_type() if nops() == 0. * * @see basic::match */ bool basic::match_same_type(const basic & /*unused*/) const { // The default is to only consider subexpressions, but not any other // attributes return true; } unsigned basic::return_type() const { return return_types::commutative; } tinfo_t basic::return_type_tinfo() const { return tinfo_key; } /** Compute the hash value of an object and if it makes sense to store it in * the objects status_flags, do so. The method inherited from class basic * computes a hash value based on the type and hash values of possible * members. For this reason it is well suited for container classes but * atomic classes should override this implementation because otherwise they * would all end up with the same hashvalue. */ long basic::calchash() const { long v = golden_ratio_hash((intptr_t)tinfo()); for (size_t i=0; iop(i).gethash(); } // store calculated hash value only if object is already evaluated if (is_evaluated()) { setflag(status_flags::hash_calculated); hashvalue = v; } return v; } /** Function object to be applied by basic::expand(). */ struct expand_map_function : public map_function { unsigned options; expand_map_function(unsigned o) : options(o) {} ex operator()(const ex & e) override { return e.expand(options); } }; /** Expand expression, i.e. multiply it out and return the result as a new * expression. */ ex basic::expand(unsigned options) const { if (nops() == 0) return (options == 0) ? setflag(status_flags::expanded) : *this; expand_map_function map_expand(options); return ex_to(map(map_expand)).setflag(options == 0 ? status_flags::expanded : 0); } ////////// // non-virtual functions in this class ////////// // public /** Compare objects syntactically to establish canonical ordering. * All compare functions return: -1 for *this less than other, 0 equal, * 1 greater. */ int basic::compare(const basic & other) const { #ifdef GINAC_COMPARE_STATISTICS compare_statistics.total_basic_compares++; #endif const long hash_this = gethash(); const long hash_other = other.gethash(); if (hash_thishash_other) return 1; #ifdef GINAC_COMPARE_STATISTICS compare_statistics.compare_same_hashvalue++; #endif const tinfo_t& typeid_this = tinfo(); const tinfo_t& typeid_other = other.tinfo(); if (typeid_this == typeid_other) { #ifdef GINAC_COMPARE_STATISTICS compare_statistics.compare_same_type++; #endif return compare_same_type(other); } return (typeid_thisgethash()!=other.gethash()) return false; #ifdef GINAC_COMPARE_STATISTICS compare_statistics.is_equal_same_hashvalue++; #endif if (this->tinfo()!=other.tinfo()) return false; GINAC_ASSERT(typeid(*this)==typeid(other)); #ifdef GINAC_COMPARE_STATISTICS compare_statistics.is_equal_same_type++; #endif return is_equal_same_type(other); } // protected /** Stop further evaluation. * * @see basic::eval */ const basic & basic::hold() const { return setflag(status_flags::evaluated); } /** Ensure the object may be modified without hurting others, throws if this * is not the case. */ void basic::ensure_if_modifiable() const { if (get_refcount() > 1) throw(std::runtime_error("cannot modify multiply referenced object")); clearflag(status_flags::hash_calculated | status_flags::evaluated); } ////////// // global variables ////////// int max_recursion_level = 1024; #ifdef GINAC_COMPARE_STATISTICS compare_statistics_t::~compare_statistics_t() { std::clog << "ex::compare() called " << total_compares << " times" << std::endl; std::clog << "nontrivial compares: " << nontrivial_compares << " times" << std::endl; std::clog << "basic::compare() called " << total_basic_compares << " times" << std::endl; std::clog << "same hashvalue in compare(): " << compare_same_hashvalue << " times" << std::endl; std::clog << "compare_same_type() called " << compare_same_type << " times" << std::endl; std::clog << std::endl; std::clog << "ex::is_equal() called " << total_is_equals << " times" << std::endl; std::clog << "nontrivial is_equals: " << nontrivial_is_equals << " times" << std::endl; std::clog << "basic::is_equal() called " << total_basic_is_equals << " times" << std::endl; std::clog << "same hashvalue in is_equal(): " << is_equal_same_hashvalue << " times" << std::endl; std::clog << "is_equal_same_type() called " << is_equal_same_type << " times" << std::endl; std::clog << std::endl; std::clog << "basic::gethash() called " << total_gethash << " times" << std::endl; std::clog << "used cached hashvalue " << gethash_cached << " times" << std::endl; } compare_statistics_t compare_statistics; #endif } // namespace GiNaC pynac-pynac-0.7.29/ginac/basic.h000066400000000000000000000270221406646613100163600ustar00rootroot00000000000000/** @file basic.h * * Interface to GiNaC's ABC. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GINAC_BASIC_H__ #define __GINAC_BASIC_H__ #include #include #include #include // CINT needs to work properly with #include #include "pynac-config.h" #include "flags.h" #include "ptr.h" #include "assertion.h" #include "registrar.h" #include "context.h" // PyObject forward declaration #ifndef PyObject_HEAD struct _object; typedef _object PyObject; #endif #ifdef PYNAC_HAVE_LIBGIAC namespace giac { class gen; template class tensor; typedef class tensor polynome; } namespace GiNaC { struct ex_is_less; } #endif namespace GiNaC { class ex; struct ex_is_less; struct ex_hash; class symbol; class numeric; class relational; class archive_node; class print_context; class flint_series_t; typedef std::vector exvector; typedef std::set exset; typedef std::map exmap; using ex_int_map = std::map; using ex_int_umap = std::unordered_map; // Define this to enable some statistical output for comparisons and hashing #undef GINAC_COMPARE_STATISTICS #ifdef GINAC_COMPARE_STATISTICS class compare_statistics_t { public: compare_statistics_t() : total_compares(0), nontrivial_compares(0), total_basic_compares(0), compare_same_hashvalue(0), compare_same_type(0), total_is_equals(0), nontrivial_is_equals(0), total_basic_is_equals(0), is_equal_same_hashvalue(0), is_equal_same_type(0), total_gethash(0), gethash_cached(0) {} ~compare_statistics_t(); unsigned long total_compares; unsigned long nontrivial_compares; unsigned long total_basic_compares; unsigned long compare_same_hashvalue; unsigned long compare_same_type; unsigned long total_is_equals; unsigned long nontrivial_is_equals; unsigned long total_basic_is_equals; unsigned long is_equal_same_hashvalue; unsigned long is_equal_same_type; unsigned long total_gethash; unsigned long gethash_cached; }; extern compare_statistics_t compare_statistics; #endif /** Function object for map(). */ struct map_function { virtual ~map_function() {} typedef const ex & argument_type; typedef ex result_type; virtual ex operator()(const ex & e) = 0; }; /** Degenerate base class for visitors. basic and derivative classes * support Robert C. Martin's Acyclic Visitor pattern (cf. * http://objectmentor.com/publications/acv.pdf). */ class visitor { protected: virtual ~visitor() {} }; /** This class is the ABC (abstract base class) of GiNaC's class hierarchy. */ class basic : public refcounted { public: typedef void inherited; static const tinfo_static_t tinfo_static; private: static registered_class_info reg_info; public: static registered_class_info &get_class_info_static() { return reg_info; } virtual const registered_class_info &get_class_info() const { return basic::get_class_info_static(); } virtual GiNaC::registered_class_info &get_class_info() { return basic::get_class_info_static(); } virtual const char *class_name() const { return basic::get_class_info_static().options.get_name(); } basic(const archive_node &n, lst &sym_lst); virtual void archive(archive_node &n) const; class visitor { public: virtual void visit(const basic &) = 0; virtual ~visitor() {}; \ }; friend class ex; friend class print_order; friend class print_order_pair; // default constructor, destructor, copy constructor and assignment operator protected: basic() : tinfo_key(&tinfo_static), flags(0) {} public: /** basic destructor, virtual because class ex will delete objects of * derived classes via a basic*. */ virtual ~basic() { GINAC_ASSERT((!(flags & status_flags::dynallocated)) || (get_refcount() == 0)); } basic(const basic & other); const basic & operator=(const basic & other); protected: /** Constructor with specified tinfo_key (used by derived classes instead * of the default constructor to avoid assigning tinfo_key twice). */ basic(tinfo_t ti) : tinfo_key(ti), flags(0) {} // new virtual functions which can be overridden by derived classes public: // only const functions please (may break reference counting) /** Create a clone of this object on the heap. One can think of this as * simulating a virtual copy constructor which is needed for instance by * the refcounted construction of an ex from a basic. */ virtual basic * duplicate() const { return new basic(*this); } // evaluation virtual ex eval(int level = 0) const; virtual ex evalf(int level = 0, PyObject* parent=nullptr) const; virtual ex evalm() const; // printing virtual void print(const print_context & c, unsigned level = 0) const; virtual void dbgprint() const; virtual void dbgprinttree() const; virtual unsigned precedence() const; // info virtual bool info(unsigned inf) const; virtual bool is_integer() const { return info(info_flags::integer); } virtual bool is_real() const { return info(info_flags::real); } virtual bool is_positive() const { return info(info_flags::positive); } virtual bool is_negative() const { return info(info_flags::negative); } // operand access virtual size_t nops() const; virtual const ex op(size_t i) const; virtual ex operator[](const ex & index) const; virtual ex operator[](size_t i) const; virtual ex & let_op(size_t i); virtual ex & operator[](const ex & index); virtual ex & operator[](size_t i); // pattern matching virtual bool has(const ex & other, unsigned options = 0) const; virtual bool match(const ex & pattern, exmap& map) const; virtual bool match_same_type(const basic & other) const; virtual void do_print(const print_context & c, unsigned level) const; virtual void do_print_tree(const print_tree & c, unsigned level) const; virtual void do_print_python_repr(const print_python_repr & c, unsigned level) const; // substitutions virtual ex subs(const exmap & m, unsigned options = 0) const; // function mapping virtual ex map(map_function & f) const; // visitors and tree traversal virtual void accept(GiNaC::visitor & v) const { if (visitor *p = dynamic_cast(&v)) p->visit(*this); } // degree/coeff virtual bool is_polynomial(const ex & var) const; virtual numeric degree(const ex & s) const; virtual numeric ldegree(const ex & s) const; virtual ex coeff(const ex & s, const ex & n) const; // expand/collect virtual ex expand(unsigned options = 0) const; virtual ex collect(const ex & s, bool distributed = false) const; // differentiation and series expansion virtual ex derivative(const symbol & s) const; virtual ex series(const relational & r, int order, unsigned options = 0) const; virtual void useries(flint_series_t& fp, int order) const {} // rational functions virtual ex normal(exmap & repl, exmap & rev_lookup, int level = 0, unsigned options = 0) const; virtual ex to_rational(exmap & repl) const; virtual ex to_polynomial(exmap & repl) const; // polynomial algorithms virtual numeric integer_content() const; virtual ex smod(const numeric &xi) const; virtual numeric max_coefficient() const; // noncommutativity virtual unsigned return_type() const; virtual tinfo_t return_type_tinfo() const; // functions for complex expressions virtual ex conjugate() const; virtual ex real_part() const; virtual ex imag_part() const; virtual int compare(const basic & other) const; // functions that should be called from class ex only virtual int compare_same_type(const basic & other) const; virtual bool is_equal_same_type(const basic & other) const; virtual long calchash() const; // non-virtual functions in this class public: /** Like print(), but dispatch to the specified class. Can be used by * implementations of print methods to dispatch to the method of the * superclass. * * @see basic::print */ template void print_dispatch(const print_context & c, unsigned level) const { print_dispatch(T::get_class_info_static(), c, level); } void print_dispatch(const registered_class_info & ri, const print_context & c, unsigned level) const; ex subs_one_level(const exmap & m, unsigned options) const; ex diff(const symbol & s, unsigned nth = 1) const; bool is_equal(const basic & other) const; bool is_evaluated() const { return global_hold or ((flags & status_flags::evaluated) != 0u); } const basic & hold() const; void set_epseq_from(size_t i, ex e); long gethash() const { #ifdef GINAC_COMPARE_STATISTICS compare_statistics.total_gethash++; #endif if (flags & status_flags::hash_calculated) { #ifdef GINAC_COMPARE_STATISTICS compare_statistics.gethash_cached++; #endif return hashvalue; } return calchash(); } tinfo_t tinfo() const {return tinfo_key;} /** Set some status_flags. */ const basic & setflag(unsigned f) const {flags |= f; return *this;} /** Clear some status_flags. */ const basic & clearflag(unsigned f) const {flags &= ~f; return *this;} void ensure_if_modifiable() const; #ifdef PYNAC_HAVE_LIBGIAC const giac::polynome to_polynome(ex_int_map& map, exvector& revmap); #endif // member variables tinfo_t tinfo_key; ///< type info mutable unsigned flags; ///< of type status_flags mutable long hashvalue=0; ///< hash value }; // global variables extern int max_recursion_level; // convenience type checker template functions /** Check if obj is a T, including base classes. */ template inline bool is_a(const basic &obj) { return dynamic_cast(&obj) != nullptr; } /** Check if obj is a T, not including base classes. */ template inline bool is_exactly_a(const basic & obj) { return obj.tinfo() == &T::tinfo_static; } /** Constructs a new (class basic or derived) B object on the heap. * * This function picks the object's ctor based on the given argument types. * * This helps the constructor of ex from basic (or a derived class B) because * then the constructor doesn't have to duplicate the object onto the heap. * See ex::construct_from_basic(const basic &) for more information. */ template inline B & dynallocate(Args &&... args) { return const_cast(static_cast((new B(std::forward(args)...))->setflag(status_flags::dynallocated))); } /** Constructs a new (class basic or derived) B object on the heap. * * This function is needed for GiNaC classes which have public ctors from * initializer lists of expressions (which are not a type and not captured * by the variadic template version). */ template inline B & dynallocate(std::initializer_list il) { return const_cast(static_cast((new B(il))->setflag(status_flags::dynallocated))); } } // namespace GiNaC #endif // ndef __GINAC_BASIC_H__ pynac-pynac-0.7.29/ginac/class_info.h000066400000000000000000000124471406646613100174240ustar00rootroot00000000000000/** @file class_info.h * * Helper templates to provide per-class information for class hierarchies. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GINAC_CLASS_INFO_H__ #define __GINAC_CLASS_INFO_H__ #include // for size_t #include #include #include #include #include #include #include namespace GiNaC { // OPT is the class that stores the actual per-class data. It must provide // get_name(), get_parent_name() and get_id() members. template class class_info { public: class_info(OPT o) : options(o), next(first), parent(nullptr) { first = this; parents_identified = false; } /** Get pointer to class_info of parent class (or NULL). */ class_info *get_parent() const { identify_parents(); return parent; } /** Find class_info by name. */ static const class_info *find(const std::string &class_name); /** Dump class hierarchy to std::cout. */ static void dump_hierarchy(bool verbose = false); OPT options; private: struct tree_node { tree_node(class_info *i) : info(i) {} void add_child(tree_node *n) { children.push_back(n); } std::vector children; class_info *info; }; static void dump_tree(tree_node *n, const std::string & prefix, bool verbose); static void identify_parents(); static class_info *first; class_info *next; mutable class_info *parent; static bool parents_identified; }; template const class_info *class_info::find(const std::string &class_name) { // Use a map for faster lookup. The registered_class_info list doesn't // change at run-time, so it's sufficient to construct the map once // on the first trip through this function. typedef std::map name_map_type; static name_map_type name_map; static bool name_map_initialized = false; if (!name_map_initialized) { // Construct map const class_info *p = first; while (p) { name_map[p->options.get_name()] = p; p = p->next; } name_map_initialized = true; } typename name_map_type::const_iterator it = name_map.find(class_name); if (it == name_map.end()) throw (std::runtime_error("class '" + class_name + "' not registered")); else return it->second; } template void class_info::dump_tree(tree_node *n, const std::string & prefix, bool verbose) { std::string name = n->info->options.get_name(); std::cout << name; if (verbose) std::cout << " [ID 0x" << std::hex << std::setw(8) << std::setfill('0') << n->info->options.get_id() << std::dec << "]" << std::endl; size_t num_children = n->children.size(); if (num_children) { for (size_t i = 0; i < num_children; ++i) { if (verbose) { std::cout << prefix << " +- "; if (i == num_children - 1) dump_tree(n->children[i], prefix + " ", verbose); else dump_tree(n->children[i], prefix + " | ", verbose); } else { std::string spaces(name.size(), ' '); if (i > 0) std::cout << prefix << spaces; if (num_children == 1) std::cout << " --- "; else if (i > 0) std::cout << " +- "; else std::cout << " -+- "; if (i == num_children - 1) dump_tree(n->children[i], prefix + spaces + " ", verbose); else dump_tree(n->children[i], prefix + spaces + " | ", verbose); } } } else if (!verbose) std::cout << std::endl; } template void class_info::dump_hierarchy(bool verbose) { identify_parents(); // Create tree nodes for all class_infos std::vector tree; for (class_info *p = first; p; p = p->next) tree.push_back(tree_node(p)); // Identify children for all nodes and find the root tree_node *root = NULL; for (const auto & elem : tree) { class_info *p = elem.info->get_parent(); if (p) { for (const auto & elem1 : tree) { if (elem1.info == p) { elem1.add_child(&elem); break; } } } else root = &elem; } // Print hierarchy tree starting at the root dump_tree(root, "", verbose); } template void class_info::identify_parents() { if (!parents_identified) { for (class_info *p = first; p; p = p->next) { const char *parent_name = p->options.get_parent_name(); for (class_info *q = first; q; q = q->next) { if (std::strcmp(q->options.get_name(), parent_name) == 0) { p->parent = q; break; } } } parents_identified = true; } } template class_info *class_info::first = nullptr; template bool class_info::parents_identified = false; } // namespace GiNaC #endif // ndef __GINAC_CLASS_INFO_H__ pynac-pynac-0.7.29/ginac/cmatcher.cpp000066400000000000000000000732641406646613100174310ustar00rootroot00000000000000// cmatcher.cpp: commutative matching // Distributed under GPL2+ // Author: 2018: Ralf Stephan // // This differs from GiNaC's original basic::match() because commutative // structures need a special algorithm. We follow the outline in // Manuel Krebber's Master Thesis, "Non-linear Associative-Commutative // Many-to-One Pattern Matching with Sequence Variables", section 3.2 // https://arxiv.org/abs/1705.00907 // // Features: // - commutative matching (sums and products, backtracking also in // powers and functions) // - more than two args with noncommutative functions // - one "global wildcard" (x^+) per sum or product // // TODO: // - "global wildcard"s (x^+) // - "zero wildcards" (matching superfluous wilds with 0(+) or 1(*) // - constant wildcards (those lacking specified symbols) // - commutative functions #include "cmatcher.h" #include "expairseq.h" #include "symbol.h" #include "wildcard.h" #include "add.h" #include "mul.h" #include "power.h" #include "function.h" #include "fderivative.h" #include "operators.h" #include "utils.h" #include #include #include namespace GiNaC { int CMatcher::level = 0; static bool trivial_match(const ex& s, const ex& pattern, exmap& map) { if (is_exactly_a(pattern)) { // Wildcard matches anything, but check whether we already have found // a match for that wildcard first (if so, the earlier match must be // the same expression) const auto& it = map.find(pattern); if (it != map.end()) return s.is_equal(ex_to(it->second)); map[pattern] = s; return true; } // Expression must be of the same type as the pattern if (s.bp->tinfo() != ex_to(pattern).tinfo()) return false; // No subexpressions (such expressions are handled in cmatch() // So just compare the objects (there can't be // wildcards in the pattern) return s.bp->is_equal_same_type(ex_to(pattern)); } inline bool is_ncfunc(const ex& e) { return is_exactly_a(e) or is_exactly_a(e) or is_exactly_a(e) or is_exactly_a(e) or is_exactly_a(e); } inline bool is_func(const ex& e) { return is_ncfunc(e) or is_a(e); } std::vector ex::all_matches(const ex & pattern) const { exmap map; std::vector vec; if (not is_func(*this)) { bool ret = bp->match(pattern, map); if (ret) vec.push_back(map); return vec; } CMatcher::level=0; CMatcher cm(*this, pattern, map); do { opt_exmap m = cm.get(); if (m) { vec.push_back(m.value()); cm.clear_ret(); if (cm.finished) break; } else break; } while (1); return vec; } inline bool CMatcher::get_alt(size_t i) { CMatcher& cm = cms[i].value(); if (cm.ret_val) { bool ret = cm.ret_val.value(); if (ret) { ret_map = cm.ret_map.value(); cm.ret_map.reset(); } cm.ret_val.reset(); return ret; } if (cm.finished) return false; bool ret; cm.map = map_repo[i]; const opt_exmap& opm = cm.get(); ret_map = opm; ret_val = ret = opm? true : false; cm.clear_ret(); if (not cm.finished) finished = false; return ret; } CMatcher::~CMatcher() { } opt_bool CMatcher::init() { bool global_wild = false; const size_t snops = source.nops(), pnops = pattern.nops(); if (is_exactly_a(pattern)) { const auto& it = map.find(pattern); finished = true; if (it != map.end()) { if (not source.is_equal(ex_to(it->second))) return false; ret_map = map; return true; } map[pattern] = source; ret_map = map; return true; } if (ex_to(source).tinfo() != ex_to(pattern).tinfo()) { return false; } if (is_exactly_a(source) and ex_to(source).get_serial() != ex_to(pattern).get_serial()) { return false; } if (snops < pnops) { return false; } symbolset oset = source.symbols(); symbolset pset = substitute(pattern.wilds(), map); if (not subset_of(pset, oset)) { return false; } // Chop into terms for (size_t i=0; i(pat[i])) wild_ind.push_back(i); if (not is_ncfunc(source)) { // source is commutative if (snops > pnops) { if (wild_ind.empty()) return false; // we have a global wildcard, i.e., one that matches // more than one term (x^+ in the paper) in a sum or // product global_wild = true; } // Check that all "constants" in the pattern are matched // Presets are already substituted now for (auto it1 = pat.begin(); it1 != pat.end(); ) { if (haswild(*it1)) { ++it1; continue; } const auto& it2 = std::find_if(ops.begin(), ops.end(), [it1](const ex& e) { return e.is_equal(*it1); } ); if (it2 != ops.end()) { (void)ops.erase(it2); it1 = pat.erase(it1); } else { return false; } } } else { // Check that all "constants" in the pattern are matched // Presets are already substituted now for (auto it1 = pat.begin(), it2 = ops.begin(); it1 != pat.end(); ) { if (haswild(*it1)) { ++it1; ++it2; continue; } if (it2->is_equal(*it1)) { it2 = ops.erase(it2); it1 = pat.erase(it1); } else { return false; } } if (pat.empty()) { finished = true; ret_map = map; return true; } } if (wild_ind.empty() and ops.empty() and pat.empty()) { finished = true; ret_map = map; return true; } if (wild_ind.empty() and (ops.empty() or pat.empty())) throw std::runtime_error("matching gotcha"); N = ops.size(); P = pat.size(); m_cmatch.assign(N, false); std::transform(pat.begin(), pat.end(), m_cmatch.begin(), [](const ex& e) { return is_func(e); } ); if (P == 1) { if (not global_wild) { if (not m_cmatch[0]) { ret_val = trivial_match(ops[0], pat[0], map); if (ret_val.value()) ret_map = map; finished = true; return ret_val.value(); } } else { // only the global wildcard left ret_val = true; ret_map = map; ex r; if (is_exactly_a(source)) { r = _ex0; for (size_t i=0; i(source)) { r = _ex1; for (size_t i=0; i(N); finished = false; perm.reserve(P); if (is_ncfunc(source)) { type = Type::noncomm; // perm is not used but needs to be filled for (size_t i=0; i= 0) { if (m_cmatch[ii] and cms[ii] and not cms[ii].value().finished) break; } size_t index; if (ii >= 0) { index = static_cast(ii); while (unsigned(++ii) < P) cms[ii].reset(); } else // no cmatcher or all uninitialized index = 0; // The second loop increases index to get a new ops term do { const ex& e = ops[index]; if (index == 0) map_repo[0] = map; else map_repo[index] = map_repo[index-1]; // At this point we try matching p to e const ex& p = pat[index]; if (not m_cmatch[index]) { // normal matching attempt exmap m = map_repo[index]; bool ret = trivial_match(e, p, m); if (ret) { map_repo[index] = m; continue; } } else { if (not cms[index]) { exmap m = map_repo[index]; cms[index].emplace(e, p, m); } else { cms[index].value().ret_val.reset(); cms[index].value().finished = false; } if (get_alt(index)) { map_repo[index] = ret_map.value(); continue; } cms[index].reset(); } bool alt_solution_found = false; int i = static_cast(index); while (--i >= 0) { if (cms[i]) { if (i == 0) map_repo[0] = map; else map_repo[i] = map_repo[i-1]; auto& cm = cms[i].value(); cm.ret_val.reset(); cm.map = map_repo[i]; if (get_alt(i)) { map_repo[i] = ret_map.value(); index = i; alt_solution_found = true; break; } else cms[i].reset(); } } if (not alt_solution_found) break; } while (++index < P); if (index >= P) { ret_val = true; ret_map = map_repo[P-1]; finished = std::all_of(cms.begin(), cms.end(), [](const opt_CMatcher& cm) { return not cm or cm.value().finished; } ); return; } finished = true; ret_map.reset(); ret_val = false; } void CMatcher::no_global_wild() { perm_run(ops, pat); } void CMatcher::perm_run(const exvector& sterms, const exvector& pterms) { // The outer loop goes though permutations of perm while (true) { int ii = P; while (--ii >= 0) { if (cms[ii] and not cms[ii].value().finished) break; } size_t index; if (ii >= 0) index = static_cast(ii); else // no cmatcher or all uninitialized or finished index = 0; while (unsigned(++ii) < P) if (cms[ii]) cms[ii].reset(); finished = true; // The second loop increases index to get a new ops term do { const ex& e = sterms[index]; if (index == 0) map_repo[0] = map; else map_repo[index] = map_repo[index-1]; // At this point we try matching p to e const ex& p = pterms[perm[index]]; if (not m_cmatch[perm[index]]) { // normal matching attempt exmap m = map_repo[index]; bool ret = trivial_match(e, p, m); if (ret) { map_repo[index] = m; continue; } } else { if (not cms[index]) { exmap m = map_repo[index]; cms[index].emplace(e, p, m); } else { cms[index].value().ret_val.reset(); cms[index].value().finished = false; } if (get_alt(index)) { map_repo[index] = ret_map.value(); continue; } cms[index].reset(); } // unfinished cmatchers in this permutation? bool alt_solution_found = false; int i = static_cast(index); while (--i >= 0) { if (cms[i]) { if (i == 0) map_repo[0] = map; else map_repo[i] = map_repo[i-1]; auto& cm = cms[i].value(); cm.ret_val.reset(); cm.map = map_repo[i]; if (get_alt(i)) { map_repo[i] = ret_map.value(); index = i; alt_solution_found = true; break; } cms[i].reset(); } } if (not alt_solution_found) break; } while (++index < P); if (index >= P) { // give back one solution of this cmatch call // possibly still permutations left if (std::all_of(cms.begin(), cms.end(), [](const opt_CMatcher& cm) { return not cm or cm.value().finished; } )) { finished = not std::next_permutation(perm.begin(), perm.end()); } else finished = false; ret_val = true; ret_map = map_repo[P-1]; return; } else { // no cmatch calls have alternative solutions // to their cmatch, so get the next permutation // that changes current index position size_t old = perm[index]; while (perm[index] == old) { bool more = std::next_permutation(perm.begin(), perm.end()); if (not more) { ret_val = false; ret_map.reset(); finished = true; return; } } } } ret_val = false; } // The case with one global wildcard term in a sum or product. // // For all wildcard terms in the pattern, we remove it and define it // as the global (so P is now one less); for all combinations of P-1 // source terms (out of N) the permutation vector is filled with 0,...,P-1 // Like before, all permutations of those P-1 source terms are matched // against the reduced patterns. When matched, those source terms not // chosen by the combination combined (+/*) are the solution of the // global wildcard. // // We call comb_run() with the following arguments: a source term vector // which contains those P-1 terms the current combination has picked out; // and the P-1 pattern terms vector (missing the current global wildcard). // comb_run() is nearly the same as perm_run(); we just need to adapt the // indices pointing to the respective entries of m_cmatch, cms, and map_repo. void CMatcher::with_global_wild() { // NOTE: P was decremented earlier do { // loop through all global wildcards // caveat: is it used elsewhere? size_t wwi = wild_ind[wi]; const wildcard& gw = ex_to(pat[wwi]); size_t ii; for (ii=0; ii(source)) gwe = _ex0; if (is_exactly_a(source)) gwe = _ex1; std::vector t(P); t.assign(ops.size(), false); for (size_t i=0; i(source)) for (size_t i=0; i(source)) for (size_t i=0; i& cmneeded) { // The outer loop goes though permutations of perm while (true) { int ii = P; while (--ii >= 0) { if (cms[comb[ii]] and not cms[comb[ii]].value().finished) break; } size_t index; if (ii >= 0) { index = static_cast(ii); } else // no cmatcher or all uninitialized index = 0; while (unsigned(++ii) < P) cms[comb[ii]].reset(); finished = true; // The second loop increases index to get a new ops term do { const ex& e = sterms[index]; if (index == 0) map_repo[comb[0]] = map; else map_repo[comb[index]] = map_repo[comb[index-1]]; // At this point we try matching p to e const ex& p = pterms[perm[index]]; if (not cmneeded[perm[index]]) { // normal matching attempt exmap m = map_repo[comb[index]]; bool ret = trivial_match(e, p, m); if (ret) { map_repo[comb[index]] = m; continue; } } else { if (not cms[comb[index]]) { exmap m = map_repo[comb[index]]; cms[comb[index]].emplace(e, p, m); } else { cms[comb[index]].value().ret_val.reset(); cms[comb[index]].value().finished = false; } if (get_alt(comb[index])) { map_repo[comb[index]] = ret_map.value(); continue; } else cms[comb[index]].reset(); } // unfinished cmatchers in this permutation? bool alt_solution_found = false; int i = static_cast(index); while (--i >= 0) { if (cms[comb[i]]) { if (i == 0) map_repo[comb[0]] = map; else map_repo[comb[i]] = map_repo[comb[i-1]]; auto& cm = cms[comb[i]].value(); cm.ret_val.reset(); cm.map = map_repo[comb[i]]; if (get_alt(comb[i])) { map_repo[comb[i]] = ret_map.value(); index = i; alt_solution_found = true; break; } cms[comb[i]].reset(); } } if (not alt_solution_found) break; } while (++index < P); if (index >= P) { // give back one solution of this cmatch call // possibly still permutations left size_t i; for (i=0; i= P) finished = not std::next_permutation(perm.begin(), perm.end()); else finished = false; ret_val = true; ret_map = map_repo[comb[P-1]]; return; } else { // no cmatch calls have alternative solutions // to their cmatch, so get the next permutation // that changes current index position size_t old = perm[index]; while (perm[index] == old) { bool more = std::next_permutation(perm.begin(), perm.end()); if (not more) { ret_val = false; ret_map.reset(); finished = true; return; } } } } ret_val = false; } } pynac-pynac-0.7.29/ginac/cmatcher.h000066400000000000000000000055371406646613100170740ustar00rootroot00000000000000#include "ex.h" #include "optional.hpp" //#include #include #include #include namespace GiNaC { struct CMatcher; using opt_exmap = nonstd::optional; using opt_bool = nonstd::optional; using opt_CMatcher = nonstd::optional; using uvec = std::vector; using nonstd::nullopt; struct CMatcher { CMatcher() { throw std::runtime_error("can't happen"); } CMatcher(const ex &source_, const ex & pattern_, const exmap& map_) : source(source_), pattern(pattern_), map(map_) { ret_val = init(); if (ret_val and not ret_val.value()) { finished = true; ret_map.reset(); } if (not ret_val) { if (type == Type::unset) throw std::runtime_error("can't happen"); } } ~CMatcher(); opt_bool init(); void run(); void noncomm_run(); void no_global_wild(); void with_global_wild(); void perm_run(const exvector&, const exvector&); void comb_run(const exvector&, const exvector&, const std::vector&); opt_exmap get() { if (ret_val) { if (not ret_val.value()) return nullopt; ret_val.reset(); return ret_map; } ret_map.reset(); ++level; run(); // guarantees to set ret, and if true, map --level; ret_val.reset(); return ret_map; } bool get_alt(size_t); void clear_ret() { ret_val.reset(); ret_map.reset(); } static int level; ex source, pattern; opt_bool ret_val; opt_exmap ret_map; exmap map; size_t N{0}, P{0}, wi{0}; exvector ops, pat, gws, gwp; std::vector cms; std::vector map_repo; std::vector m_cmatch, mcm; bool finished{false}; uvec perm, comb, wild_ind; enum Type { unset, comm, noncomm, comm_plus }; Type type {unset}; }; #if 0 struct opt_CMatcher { std::shared_ptr p; opt_CMatcher() {} opt_CMatcher(const ex &source_, const ex & pattern_, const exmap& map_) { p = std::make_shared(source_, pattern_, map_); } explicit operator bool() const { return p != nullptr; } CMatcher& value() const { if (p) return *p; throw std::logic_error("opt_CMatcher unavailable"); } void reset() { p.reset(); } }; #endif } pynac-pynac-0.7.29/ginac/compiler.h000066400000000000000000000004341406646613100171070ustar00rootroot00000000000000#ifndef GINAC_COMPILER_DEP_HH #define GINAC_COMPILER_DEP_HH #ifdef __GNUC__ #define unlikely(cond) __builtin_expect((cond), 0) #define likely(cond) __builtin_expect((cond), 1) #else #define unlikely(cond) (cond) #define likely(cond) (cond) #endif #endif /* GINAC_COMPILER_DEP_HH */ pynac-pynac-0.7.29/ginac/constant.cpp000066400000000000000000000171521406646613100174660ustar00rootroot00000000000000/** @file constant.cpp * * Implementation of GiNaC's constant types and some special constants. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define register #include #include "py_funcs.h" #include "constant.h" #include "numeric.h" #include "ex.h" #include "archive.h" #include "utils.h" #include "inifcns.h" #include #include #include namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(constant, basic, print_func(&constant::do_print). print_func(&constant::do_print_latex). print_func(&constant::do_print_tree). print_func(&constant::do_print_python_repr)) ////////// // default constructor ////////// // public constant::constant() : basic(&constant::tinfo_static), ef(nullptr), serial(next_serial++), domain(domain::complex) { setflag(status_flags::evaluated | status_flags::expanded); } ////////// // other constructors ////////// // public constant::constant(std::string initname, evalffunctype efun, const std::string & texname, unsigned dm) : basic(&constant::tinfo_static), name(std::move(initname)), ef(efun), serial(next_serial++), domain(dm) { if (texname.empty()) TeX_name = "\\mbox{" + name + "}"; else TeX_name = texname; setflag(status_flags::evaluated | status_flags::expanded); } constant::constant(std::string initname, const numeric & initnumber, const std::string & texname, unsigned dm) : basic(&constant::tinfo_static), name(std::move(initname)), ef(nullptr), number(initnumber), serial(next_serial++), domain(dm) { if (texname.empty()) TeX_name = "\\mbox{" + name + "}"; else TeX_name = texname; setflag(status_flags::evaluated | status_flags::expanded); } ////////// // archiving ////////// constant::constant(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) {} ex constant::unarchive(const archive_node &n, lst &sym_lst) { // Find constant by name (!! this is bad: 'twould be better if there // was a list of all global constants that we could search) constant ans; std::string s; if (n.find_string("name", s)) { if (s == Pi.name) return Pi; if (s == Catalan.name) return Catalan; if (s == Euler.name) return Euler; if (s == NaN.name) return NaN; ans = py_funcs.py_get_constant(s.c_str()); if (PyErr_Occurred() != nullptr) throw std::runtime_error("error while unarchiving constant"); return ans; } throw (std::runtime_error("unnamed constant in archive")); } void constant::archive(archive_node &n) const { inherited::archive(n); n.add_string("name", name); } ////////// // functions overriding virtual functions from base classes ////////// // public void constant::do_print(const print_context & c, unsigned level) const { c.s << name; } void constant::do_print_tree(const print_tree & c, unsigned level) const { c.s << std::string(level, ' ') << name << " (" << class_name() << ")" << " @" << this << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec << std::endl; } void constant::do_print_latex(const print_latex & c, unsigned level) const { c.s << TeX_name; } void constant::do_print_python_repr(const print_python_repr & c, unsigned level) const { c.s << class_name() << "('" << name << "'"; if (TeX_name != "\\mbox{" + name + "}") c.s << ",TeX_name='" << TeX_name << "'"; c.s << ')'; } bool constant::info(unsigned inf) const { if (name == "NaN") return false; switch (inf) { case info_flags::polynomial: return true; case info_flags::inexact: return false; case info_flags::real: return domain == domain::real or domain == domain::positive; case info_flags::positive: return domain == domain::positive; case info_flags::nonnegative: return domain == domain::positive and evalf(0, nullptr).is_zero(); case info_flags::nonzero: return domain == domain::positive or not evalf(0, nullptr).is_zero(); case info_flags::infinity: return domain == domain::infinity; default: return evalf(0, nullptr).info(inf); } } ex constant::evalf(int level, PyObject* parent) const { if (ef!=nullptr) return ef(serial, parent); return number.evalf(level, parent); } bool constant::is_polynomial(const ex & var) const { return true; } ex constant::conjugate() const { if ( domain==domain::real || domain==domain::positive ) return *this; return conjugate_function(*this).hold(); } ex constant::real_part() const { if ( domain==domain::real || domain==domain::positive ) return *this; return real_part_function(*this).hold(); } ex constant::imag_part() const { if ( domain==domain::real || domain==domain::positive ) return _ex0; return imag_part_function(*this).hold(); } // protected /** Implementation of ex::diff() for a constant always returns 0. * * @see ex::diff */ ex constant::derivative(const symbol & s) const { return _ex0; } int constant::compare_same_type(const basic & other) const { GINAC_ASSERT(is_exactly_a(other)); const constant &o = static_cast(other); if (serial == o.serial) return 0; return serial < o.serial ? -1 : 1; } bool constant::is_equal_same_type(const basic & other) const { GINAC_ASSERT(is_exactly_a(other)); const constant &o = static_cast(other); return serial == o.serial; } long constant::calchash() const { hashvalue = golden_ratio_hash((intptr_t)tinfo() ^ serial); setflag(status_flags::hash_calculated); return hashvalue; } ////////// // new virtual functions which can be overridden by derived classes ////////// // none ////////// // non-virtual functions in this class ////////// // none ////////// // static member variables ////////// unsigned constant::next_serial = 0; ////////// // global constants ////////// // DANGER! Defining a constant here without equivalent in Sage Python // will inevitably lead to crashes. See alsd // https://github.com/pynac/pynac/wiki/%7C-constants // https://github.com/pynac/pynac/issues/211 /** Pi. (3.14159...) Calls python function py_eval_constant() for evalf(). */ const constant Pi("pi", ConstantEvalf, "\\pi", domain::positive); /** Euler's constant. (0.57721...) Sometimes called Euler-Mascheroni constant. * Calls python function py_eval_consant for evalf(). */ const constant Euler("euler_gamma", ConstantEvalf, "\\gamma_E", domain::positive); /** Catalan's constant. (0.91597...) * Calls python function py_eval_constant for evalf(). */ const constant Catalan("catalan", ConstantEvalf, "G", domain::positive); /** Not a number * Calls python function py_eval_constant for evalf(). */ const constant NaN("NaN", ConstantEvalf, "NaN", domain::complex); } // namespace GiNaC pynac-pynac-0.7.29/ginac/constant.h000066400000000000000000000063251406646613100171330ustar00rootroot00000000000000/** @file constant.h * * Interface to GiNaC's constant types and some special constants. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GINAC_CONSTANT_H__ #define __GINAC_CONSTANT_H__ #include "basic.h" #include "ex.h" #include namespace GiNaC { typedef ex (*evalffunctype)(unsigned serial, PyObject* parent); /** This class holds constants, symbols with specific numerical value. Each * object of this class must either provide their own function to evaluate it * to class numeric or provide the constant as a numeric (if it's an exact * number). */ class constant : public basic { GINAC_DECLARE_REGISTERED_CLASS(constant, basic) // member functions // other constructors public: constant(std::string initname, evalffunctype efun = nullptr, const std::string & texname = std::string(), unsigned domain = domain::complex); constant(std::string initname, const numeric & initnumber, const std::string & texname = std::string(), unsigned domain = domain::complex); // functions overriding virtual functions from base classes public: bool info(unsigned inf) const override; ex evalf(int level = 0, PyObject* parent=nullptr) const override; bool is_polynomial(const ex & var) const override; ex conjugate() const override; ex real_part() const override; ex imag_part() const override; unsigned get_serial() const {return serial;} static ex unarchive(const archive_node &n, lst &sym_lst); protected: ex derivative(const symbol & s) const override; bool is_equal_same_type(const basic & other) const override; long calchash() const override; // non-virtual functions in this class protected: void do_print(const print_context & c, unsigned level) const override; void do_print_tree(const print_tree & c, unsigned level) const override; void do_print_latex(const print_latex & c, unsigned level) const; void do_print_python_repr(const print_python_repr & c, unsigned level) const override; // member variables private: std::string name; ///< printname of this constant std::string TeX_name; ///< LaTeX name evalffunctype ef; ex number; ///< numerical value this constant evalf()s to unsigned serial; ///< unique serial number for comparison static unsigned next_serial; unsigned domain; ///< numerical value this constant evalf()s to }; extern const constant Pi; extern const constant Catalan; extern const constant Euler; extern const constant NaN; } // namespace GiNaC #endif // ndef __GINAC_CONSTANT_H__ pynac-pynac-0.7.29/ginac/container.h000066400000000000000000000616001406646613100172610ustar00rootroot00000000000000/** @file container.h * * Wrapper template for making GiNaC classes out of STL containers. */ /* * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GINAC_CONTAINER_H__ #define __GINAC_CONTAINER_H__ #include "ex.h" #include "print.h" #include "archive.h" #include "assertion.h" #include #include #include #include #include #include #include namespace GiNaC { /** Helper template for encapsulating the reserve() mechanics of STL containers. */ template